Compare commits

..

1 Commits

Author SHA1 Message Date
15bbbf3788 chore(deps): update alpine docker tag to v3.17 2022-11-16 22:00:59 +00:00
25 changed files with 888 additions and 1150 deletions

View File

@ -377,7 +377,7 @@ steps:
event: [ push, tag, pull_request ]
- name: before-static-build
image: techknowlogick/xgo:go-1.19.2
image: techknowlogick/xgo:latest
pull: true
commands:
- export PATH=$PATH:$GOPATH/bin
@ -386,7 +386,7 @@ steps:
depends_on: [ fetch-tags, mage ]
- name: static-build-windows
image: techknowlogick/xgo:go-1.19.2
image: techknowlogick/xgo:latest
pull: true
environment:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
@ -399,7 +399,7 @@ steps:
depends_on: [ before-static-build ]
- name: static-build-linux
image: techknowlogick/xgo:go-1.19.2
image: techknowlogick/xgo:latest
pull: true
environment:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
@ -412,7 +412,7 @@ steps:
depends_on: [ before-static-build ]
- name: static-build-darwin
image: techknowlogick/xgo:go-1.19.2
image: techknowlogick/xgo:latest
pull: true
environment:
# This path does not exist. However, when we set the gopath to /go, the build fails. Not sure why.
@ -435,7 +435,7 @@ steps:
- ./mage-static release:compress
- name: after-build-static
image: techknowlogick/xgo:go-1.19.2
image: techknowlogick/xgo:latest
pull: true
depends_on:
- after-build-compress
@ -504,7 +504,7 @@ steps:
# Build os packages and push it to our bucket
- name: build-os-packages-unstable
image: goreleaser/nfpm:v2.22.2
image: goreleaser/nfpm
pull: true
commands:
- apk add git go
@ -517,10 +517,10 @@ steps:
- main
event:
- push
depends_on: [ after-build-compress ]
depends_on: [ static-build-linux ]
- name: build-os-packages-version
image: goreleaser/nfpm:v2.22.2
image: goreleaser/nfpm
pull: true
commands:
- apk add git go
@ -531,7 +531,7 @@ steps:
when:
event:
- tag
depends_on: [ after-build-compress ]
depends_on: [ static-build-linux ]
# Push the os releases to our pseudo-s3-bucket
- name: release-os-latest
@ -719,6 +719,6 @@ steps:
- failure
---
kind: signature
hmac: f3b261d9329113993cdf8ae785daee6f0b2c0ea38662d2714385d7a31f7e5b2f
hmac: 768d54fc8433705fb63f754adf19536a16152a4046a040afdbcbb7df60614056
...

View File

@ -1,7 +1,7 @@
##############
# Build stage
FROM --platform=$BUILDPLATFORM techknowlogick/xgo:go-1.19.2 AS build-env
FROM --platform=$BUILDPLATFORM techknowlogick/xgo:latest AS build-env
RUN \
go install github.com/magefile/mage@latest && \
@ -23,7 +23,7 @@ RUN if [ -n "${VIKUNJA_VERSION}" ]; then git checkout "${VIKUNJA_VERSION}"; fi &
# The actual image
# Note: I wanted to use the scratch image here, but unfortunatly the go-sqlite bindings require cgo and
# because of this, the container would not start when I compiled the image without cgo.
FROM alpine:3.16
FROM alpine:3.17
LABEL maintainer="maintainers@vikunja.io"
WORKDIR /app/vikunja/

View File

@ -311,9 +311,6 @@ auth:
- name:
# The auth url to send users to if they want to authenticate using OpenID Connect.
authurl:
# The oidc logouturl that users will be redirected to on logout.
# Leave empty or delete key, if you do not want to be redirected.
logouturl:
# The client ID used to authenticate Vikunja at the OpenID Connect provider.
clientid:
# The client secret used to authenticate Vikunja at the OpenID Connect provider.

View File

@ -10,6 +10,6 @@ menu:
There are two third-party Helm-Charts which can be used to host Vikunja with k8s:
* [Truecharts](https://truecharts.org/charts/stable/vikunja/)
* [Truecharts](https://truecharts.org/docs/charts/stable/vikunja/)
* [k8s at Home](https://github.com/k8s-at-home/charts)

35
go.mod
View File

@ -21,7 +21,7 @@ require (
gitea.com/xorm/xorm-redis-cache v0.2.0
github.com/ThreeDotsLabs/watermill v1.1.1
github.com/adlio/trello v1.10.0
github.com/arran4/golang-ical v0.0.0-20221122102835-109346913e54
github.com/arran4/golang-ical v0.0.0-20220517104411-fd89fefb0182
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef
github.com/bbrks/go-blurhash v1.1.1
github.com/c2h5oh/datasize v0.0.0-20220606134207-859f65c6625b
@ -31,25 +31,24 @@ require (
github.com/disintegration/imaging v1.6.2
github.com/dustinkirkland/golang-petname v0.0.0-20191129215211-8e5a1ed0cff0
github.com/gabriel-vasile/mimetype v1.4.1
github.com/getsentry/sentry-go v0.16.0
github.com/getsentry/sentry-go v0.15.0
github.com/go-redis/redis/v8 v8.11.5
github.com/go-sql-driver/mysql v1.7.0
github.com/go-sql-driver/mysql v1.6.0
github.com/go-testfixtures/testfixtures/v3 v3.8.1
github.com/golang-jwt/jwt/v4 v4.4.3
github.com/golang-jwt/jwt/v4 v4.4.2
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/google/uuid v1.3.0
github.com/iancoleman/strcase v0.2.0
github.com/imdario/mergo v0.3.13
github.com/jinzhu/copier v0.3.5
github.com/labstack/echo-jwt/v4 v4.0.0
github.com/labstack/echo/v4 v4.10.0
github.com/labstack/echo/v4 v4.9.1
github.com/labstack/gommon v0.4.0
github.com/lib/pq v1.10.7
github.com/magefile/mage v1.14.0
github.com/mattn/go-sqlite3 v1.14.16
github.com/olekukonko/tablewriter v0.0.5
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
github.com/pquerna/otp v1.4.0
github.com/pquerna/otp v1.3.0
github.com/prometheus/client_golang v1.14.0
github.com/robfig/cron/v3 v3.0.1
github.com/samedi/caldav-go v3.0.0+incompatible
@ -57,18 +56,18 @@ require (
github.com/spf13/cobra v1.6.1
github.com/spf13/viper v1.14.0
github.com/stretchr/testify v1.8.1
github.com/swaggo/swag v1.8.9
github.com/swaggo/swag v1.8.7
github.com/tkuchiki/go-timezone v0.2.2
github.com/ulule/limiter/v3 v3.10.0
github.com/vectordotdev/go-datemath v0.1.1-0.20211214182920-0a4ac8742b93
github.com/wneessen/go-mail v0.3.6
github.com/wneessen/go-mail v0.3.4
github.com/yuin/goldmark v1.5.3
golang.org/x/crypto v0.4.0
golang.org/x/image v0.2.0
golang.org/x/oauth2 v0.3.0
golang.org/x/crypto v0.2.0
golang.org/x/image v0.1.0
golang.org/x/oauth2 v0.1.0
golang.org/x/sync v0.1.0
golang.org/x/sys v0.3.0
golang.org/x/term v0.3.0
golang.org/x/sys v0.2.0
golang.org/x/term v0.2.0
gopkg.in/d4l3k/messagediff.v1 v1.2.1
gopkg.in/yaml.v3 v3.0.1
src.techknowlogick.com/xgo v1.5.1-0.20220906164532-735bfdfb90d9
@ -134,11 +133,11 @@ require (
github.com/syndtr/goleveldb v1.0.0 // indirect
github.com/urfave/cli/v2 v2.3.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.4.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/net v0.2.0 // indirect
golang.org/x/text v0.4.0 // indirect
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
golang.org/x/tools v0.1.12 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.1 // indirect

102
go.sum
View File

@ -99,8 +99,8 @@ github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/arran4/golang-ical v0.0.0-20221122102835-109346913e54 h1:HfAA5Vxbo64UTckj+EW/hfBjvvcUcbcwWCASvypy8JU=
github.com/arran4/golang-ical v0.0.0-20221122102835-109346913e54/go.mod h1:BSTTrYHuM12oAL8jDdcmPdw02SBThKYWNFHQlvEG6b0=
github.com/arran4/golang-ical v0.0.0-20220517104411-fd89fefb0182 h1:mUsKridvWp4dgfkO/QWtgGwuLtZYpjKgsm15JRRik3o=
github.com/arran4/golang-ical v0.0.0-20220517104411-fd89fefb0182/go.mod h1:BSTTrYHuM12oAL8jDdcmPdw02SBThKYWNFHQlvEG6b0=
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
@ -198,14 +198,18 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/gabriel-vasile/mimetype v1.4.1 h1:TRWk7se+TOjCYgRth7+1/OYLNiRNIotknkFtf/dnN7Q=
github.com/gabriel-vasile/mimetype v1.4.1/go.mod h1:05Vi0w3Y9c/lNvJOdmIwvrrAhX3rYhfQQCaf9VJcv7M=
github.com/garyburd/redigo v1.6.0 h1:0VruCpn7yAIIu7pWVClQC8wxCJEcG3nyzpMSHKi1PQc=
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/getsentry/sentry-go v0.16.0 h1:owk+S+5XcgJLlGR/3+3s6N4d+uKwqYvh/eS0AIMjPWo=
github.com/getsentry/sentry-go v0.16.0/go.mod h1:ZXCloQLj0pG7mja5NK6NPf2V4A88YJ4pNlc2mOHwh6Y=
github.com/getsentry/sentry-go v0.14.0 h1:rlOBkuFZRKKdUnKO+0U3JclRDQKlRu5vVQtkWSQvC70=
github.com/getsentry/sentry-go v0.14.0/go.mod h1:RZPJKSw+adu8PBNygiri/A98FqVr2HtRckJk9XVxJ9I=
github.com/getsentry/sentry-go v0.15.0 h1:CP9bmA7pralrVUedYZsmIHWpq/pBtXTSew7xvVpfLaA=
github.com/getsentry/sentry-go v0.15.0/go.mod h1:RZPJKSw+adu8PBNygiri/A98FqVr2HtRckJk9XVxJ9I=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAUcHlgXVRs=
@ -238,9 +242,8 @@ github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
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.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-testfixtures/testfixtures/v3 v3.8.1 h1:uonwvepqRvSgddcrReZQhojTlWlmOlHkYAb9ZaOMWgU=
github.com/go-testfixtures/testfixtures/v3 v3.8.1/go.mod h1:Kdu7YeMC0KRXVHdaQ91Vmx3pcjoTF63h4f1qTJDdXLA=
@ -255,8 +258,8 @@ github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU=
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs=
github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
@ -498,11 +501,9 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo-jwt/v4 v4.0.0 h1:MFdURJRtBNWzADUdXYlj++71UZ5MmjUtce7nSsCH8NY=
github.com/labstack/echo-jwt/v4 v4.0.0/go.mod h1:DHSSaL6cTgczdPXjf8qrTHRbrau2flcddV7CPMs2U/Y=
github.com/labstack/echo/v4 v4.1.16/go.mod h1:awO+5TzAjvL8XpibdsfXxPgHr+orhtXZJZIQCVjogKI=
github.com/labstack/echo/v4 v4.10.0 h1:5CiyngihEO4HXsz3vVsJn7f8xAlWwRr3aY6Ih280ZKA=
github.com/labstack/echo/v4 v4.10.0/go.mod h1:S/T/5fy/GigaXnHTkh0ZGe4LpkkQysvRjFMSUTkDRNQ=
github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y=
github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
@ -557,6 +558,8 @@ github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
@ -632,8 +635,8 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/pquerna/otp v1.3.0 h1:oJV/SkzR33anKXwQU3Of42rL4wbrffP4uvUf1SvS5Xs=
github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
@ -641,6 +644,10 @@ github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeD
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.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU=
github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
github.com/prometheus/client_golang v1.13.1 h1:3gMjIY2+/hzmqhtUC/aQNYldJA6DtH3CgQvwS+02K1c=
github.com/prometheus/client_golang v1.13.1/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@ -648,6 +655,7 @@ github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
@ -701,11 +709,15 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw=
github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
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.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI=
github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
@ -713,6 +725,8 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU=
github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw=
github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU=
github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
@ -730,13 +744,14 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/swaggo/swag v1.8.9 h1:kHtaBe/Ob9AZzAANfcn5c6RyCke9gG9QpH0jky0I/sA=
github.com/swaggo/swag v1.8.9/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
github.com/swaggo/swag v1.8.7 h1:2K9ivTD3teEO+2fXV6zrZKDqk5IuU2aJtBDo8U7omWU=
github.com/swaggo/swag v1.8.7/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/tkuchiki/go-timezone v0.2.2 h1:MdHR65KwgVTwWFQrota4SKzc4L5EfuH5SdZZGtk/P2Q=
@ -753,13 +768,18 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.2.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
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/vectordotdev/go-datemath v0.1.1-0.20211214182920-0a4ac8742b93 h1:bT0ZMfsMi2Xh8dopgxhFT+OJH88QITHpdppdkG1rXJQ=
github.com/vectordotdev/go-datemath v0.1.1-0.20211214182920-0a4ac8742b93/go.mod h1:PnwzbSst7KD3vpBzzlntZU5gjVa455Uqa5QPiKSYJzQ=
github.com/wneessen/go-mail v0.3.6 h1:hT8PMIBdcTkoiDwoUGJssPYOe1Gg1/cUcp2o9+ls63o=
github.com/wneessen/go-mail v0.3.6/go.mod h1:m25lkU2GYQnlVr6tdwK533/UXxo57V0kLOjaFYmub0E=
github.com/wneessen/go-mail v0.3.1 h1:9hSthi8T57gDHMI0fgl58O667OQJm9wZ1EHyuy3hclA=
github.com/wneessen/go-mail v0.3.1/go.mod h1:m25lkU2GYQnlVr6tdwK533/UXxo57V0kLOjaFYmub0E=
github.com/wneessen/go-mail v0.3.2 h1:nTjAF4Ek2+JG7qunyk6oImf5YKrAE5a7A3uIazYsdM0=
github.com/wneessen/go-mail v0.3.2/go.mod h1:m25lkU2GYQnlVr6tdwK533/UXxo57V0kLOjaFYmub0E=
github.com/wneessen/go-mail v0.3.3 h1:mhqM18uWiBFA3TdfO2IyFfQ6dEj4kGKW1KQJJNSKLME=
github.com/wneessen/go-mail v0.3.3/go.mod h1:m25lkU2GYQnlVr6tdwK533/UXxo57V0kLOjaFYmub0E=
github.com/wneessen/go-mail v0.3.4 h1:75G6lojt3CxwSq73csMduxF7DJ3hLF2s2KJXJVDOr0k=
github.com/wneessen/go-mail v0.3.4/go.mod h1:m25lkU2GYQnlVr6tdwK533/UXxo57V0kLOjaFYmub0E=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -767,6 +787,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.5.2 h1:ALmeCk/px5FSm1MAcFBAsVKZjDuMVj8Tm7FFIlMJnqU=
github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.5.3 h1:3HUJmBFbQW9fhQOzMgseU134xfi6hU+mjWywx5Ty+/M=
github.com/yuin/goldmark v1.5.3/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
@ -815,8 +837,10 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/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.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE=
golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -830,8 +854,8 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.2.0 h1:/DcQ0w3VHKCC5p0/P2B0JpAZ9Z++V2KOo2fyU89CXBQ=
golang.org/x/image v0.2.0/go.mod h1:la7oBXb9w3YFjBqaAwtynVioc1ZvOnNteUNrifGNmAI=
golang.org/x/image v0.1.0 h1:r8Oj8ZA2Xy12/b5KZYj3tuv7NG/fBz3TwQVvpJ9l8Rk=
golang.org/x/image v0.1.0/go.mod h1:iyPr49SD/G/TBxYVB/9RRtGUT5eNbo2u4NamWeQcD5c=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -913,8 +937,10 @@ golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -936,8 +962,8 @@ golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.3.0 h1:6l90koy8/LaBLmLu8jpHeHexzMwEita0zFfYlggy2F8=
golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk=
golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y=
golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -1046,13 +1072,17 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
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-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
golang.org/x/sys v0.2.0/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/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/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.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1062,15 +1092,15 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/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.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@ -703,7 +703,7 @@ func (Release) Packages() error {
binpath := "nfpm"
err = exec.Command(binpath).Run()
if err != nil && strings.Contains(err.Error(), "executable file not found") {
binpath = "/usr/bin/nfpm"
binpath = "/nfpm"
err = exec.Command(binpath).Run()
}
if err != nil && strings.Contains(err.Error(), "executable file not found") {
@ -712,7 +712,7 @@ func (Release) Packages() error {
os.Exit(1)
}
// Because nfpm does not support templating, we replace the values in the config file and restore it after running
// Because nfpm does not support templating, we replace the values in the config file and restore it after running
nfpmConfigPath := RootPath + "/nfpm.yaml"
nfpmconfig, err := os.ReadFile(nfpmConfigPath)
if err != nil {

View File

@ -22,8 +22,7 @@ import (
"strings"
"time"
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/config"
"code.vikunja.io/api/pkg/user"
"code.vikunja.io/api/pkg/utils"
)
@ -59,12 +58,10 @@ type Todo struct {
RelatedToUID string
Color string
Start time.Time
End time.Time
DueDate time.Time
Duration time.Duration
RepeatAfter int64
RepeatMode models.TaskRepeatMode
Start time.Time
End time.Time
DueDate time.Time
Duration time.Duration
Created time.Time
Updated time.Time // last-mod
@ -229,16 +226,6 @@ CREATED:` + makeCalDavTimeFromTimeStamp(t.Created)
PRIORITY:` + strconv.Itoa(mapPriorityToCaldav(t.Priority))
}
if t.RepeatAfter > 0 || t.RepeatMode == models.TaskRepeatModeMonth {
if t.RepeatMode == models.TaskRepeatModeMonth {
caldavtodos += `
RRULE:FREQ=MONTHLY;BYMONTHDAY=` + t.DueDate.Format("02") // Day of the month
} else {
caldavtodos += `
RRULE:FREQ=SECONDLY;INTERVAL=` + strconv.FormatInt(t.RepeatAfter, 10)
}
}
caldavtodos += `
LAST-MODIFIED:` + makeCalDavTimeFromTimeStamp(t.Updated)
@ -253,7 +240,7 @@ END:VCALENDAR` // Need a line break
}
func makeCalDavTimeFromTimeStamp(ts time.Time) (caldavtime string) {
return ts.In(time.UTC).Format(DateFormat) + "Z"
return ts.In(config.GetTimeZone()).Format(DateFormat)
}
func calcAlarmDateFromReminder(eventStart, reminder time.Time) (alarmTime string) {

View File

@ -20,8 +20,6 @@ import (
"testing"
"time"
"code.vikunja.io/api/pkg/models"
"code.vikunja.io/api/pkg/config"
"github.com/stretchr/testify/assert"
)
@ -86,25 +84,25 @@ X-APPLE-CALENDAR-COLOR:#affffeFF
X-OUTLOOK-COLOR:#affffeFF
X-FUNAMBOL-COLOR:#affffeFF
DESCRIPTION:Lorem Ipsum
DTSTAMP:20181201T011204Z
DTSTART:20181201T011204Z
DTEND:20181201T013024Z
DTSTAMP:20181201T011204
DTSTART:20181201T011204
DTEND:20181201T013024
END:VEVENT
BEGIN:VEVENT
UID:randommduidd
SUMMARY:Event #2
DESCRIPTION:
DTSTAMP:20181202T045844Z
DTSTART:20181202T045844Z
DTEND:20181202T081844Z
DTSTAMP:20181202T045844
DTSTART:20181202T045844
DTEND:20181202T081844
END:VEVENT
BEGIN:VEVENT
UID:20181202T0600242aaef4a81d770c1e775e26bc5abebc87f1d3d7bffaa83
SUMMARY:Event #3 with empty uid
DESCRIPTION:
DTSTAMP:20181202T050024Z
DTSTART:20181202T050024Z
DTEND:20181202T050320Z
DTSTAMP:20181202T050024
DTSTART:20181202T050024
DTEND:20181202T050320
END:VEVENT
END:VCALENDAR`,
},
@ -171,9 +169,9 @@ BEGIN:VEVENT
UID:randommduid
SUMMARY:Event #1
DESCRIPTION:Lorem Ipsum
DTSTAMP:20181201T011204Z
DTSTART:20181201T011204Z
DTEND:20181201T013024Z
DTSTAMP:20181201T011204
DTSTART:20181201T011204
DTEND:20181201T013024
BEGIN:VALARM
TRIGGER:-PT3M20S
ACTION:DISPLAY
@ -194,9 +192,9 @@ BEGIN:VEVENT
UID:randommduidd
SUMMARY:Event #2
DESCRIPTION:
DTSTAMP:20181202T045844Z
DTSTART:20181202T045844Z
DTEND:20181202T081844Z
DTSTAMP:20181202T045844
DTSTART:20181202T045844
DTEND:20181202T081844
BEGIN:VALARM
TRIGGER:-PT27H50M0S
ACTION:DISPLAY
@ -214,12 +212,12 @@ DESCRIPTION:Event #2
END:VALARM
END:VEVENT
BEGIN:VEVENT
UID:20181202T050024Z2aaef4a81d770c1e775e26bc5abebc87f1d3d7bffaa83
UID:20181202T0500242aaef4a81d770c1e775e26bc5abebc87f1d3d7bffaa83
SUMMARY:Event #3 with empty uid
DESCRIPTION:
DTSTAMP:20181202T050024Z
DTSTART:20181202T050024Z
DTEND:20181202T050320Z
DTSTAMP:20181202T050024
DTSTART:20181202T050024
DTEND:20181202T050320
BEGIN:VALARM
TRIGGER:-PT27H51M40S
ACTION:DISPLAY
@ -242,12 +240,12 @@ DESCRIPTION:Event #3 with empty uid
END:VALARM
END:VEVENT
BEGIN:VEVENT
UID:20181202T050024Zae7548ce9556df85038abe90dc674d4741a61ce74d1cf
UID:20181202T050024ae7548ce9556df85038abe90dc674d4741a61ce74d1cf
SUMMARY:Event #4 without any
DESCRIPTION:
DTSTAMP:20181202T050024Z
DTSTART:20181202T050024Z
DTEND:20181202T050320Z
DTSTAMP:20181202T050024
DTSTART:20181202T050024
DTEND:20181202T050320
END:VEVENT
END:VCALENDAR`,
},
@ -280,9 +278,9 @@ BEGIN:VEVENT
UID:randommduid
SUMMARY:Event #1
DESCRIPTION:Lorem Ipsum\nDolor sit amet
DTSTAMP:20181201T011204Z
DTSTART:20181201T011204Z
DTEND:20181201T013024Z
DTSTAMP:20181201T011204
DTSTART:20181201T011204
DTEND:20181201T013024
END:VEVENT
END:VCALENDAR`,
},
@ -335,13 +333,13 @@ X-OUTLOOK-COLOR:#ffffffFF
X-FUNAMBOL-COLOR:#ffffffFF
BEGIN:VTODO
UID:randommduid
DTSTAMP:20181201T011204Z
DTSTAMP:20181201T011204
SUMMARY:Todo #1
X-APPLE-CALENDAR-COLOR:#affffeFF
X-OUTLOOK-COLOR:#affffeFF
X-FUNAMBOL-COLOR:#affffeFF
DESCRIPTION:Lorem Ipsum\nDolor sit amet
LAST-MODIFIED:00010101T000000Z
LAST-MODIFIED:00010101T000000
END:VTODO
END:VCALENDAR`,
},
@ -370,12 +368,12 @@ X-WR-CALNAME:test
PRODID:-//RandomProdID which is not random//EN
BEGIN:VTODO
UID:randommduid
DTSTAMP:20181201T011204Z
DTSTAMP:20181201T011204
SUMMARY:Todo #1
DESCRIPTION:Lorem Ipsum
COMPLETED:20181201T013024Z
COMPLETED:20181201T013024
STATUS:COMPLETED
LAST-MODIFIED:00010101T000000Z
LAST-MODIFIED:00010101T000000
END:VTODO
END:VCALENDAR`,
},
@ -404,82 +402,11 @@ X-WR-CALNAME:test
PRODID:-//RandomProdID which is not random//EN
BEGIN:VTODO
UID:randommduid
DTSTAMP:20181201T011204Z
DTSTAMP:20181201T011204
SUMMARY:Todo #1
DESCRIPTION:Lorem Ipsum
PRIORITY:9
LAST-MODIFIED:00010101T000000Z
END:VTODO
END:VCALENDAR`,
},
{
name: "with repeating monthly",
args: args{
config: &Config{
Name: "test",
ProdID: "RandomProdID which is not random",
},
todos: []*Todo{
{
Summary: "Todo #1",
Description: "Lorem Ipsum",
UID: "randommduid",
Timestamp: time.Unix(1543626724, 0).In(config.GetTimeZone()),
RepeatMode: models.TaskRepeatModeMonth,
DueDate: time.Unix(1543626724, 0).In(config.GetTimeZone()),
},
},
},
wantCaldavtasks: `BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
X-PUBLISHED-TTL:PT4H
X-WR-CALNAME:test
PRODID:-//RandomProdID which is not random//EN
BEGIN:VTODO
UID:randommduid
DTSTAMP:20181201T011204Z
SUMMARY:Todo #1
DESCRIPTION:Lorem Ipsum
DUE:20181201T011204Z
RRULE:FREQ=MONTHLY;BYMONTHDAY=01
LAST-MODIFIED:00010101T000000Z
END:VTODO
END:VCALENDAR`,
},
{
name: "with repeat mode default",
args: args{
config: &Config{
Name: "test",
ProdID: "RandomProdID which is not random",
},
todos: []*Todo{
{
Summary: "Todo #1",
Description: "Lorem Ipsum",
UID: "randommduid",
Timestamp: time.Unix(1543626724, 0).In(config.GetTimeZone()),
RepeatMode: models.TaskRepeatModeDefault,
DueDate: time.Unix(1543626724, 0).In(config.GetTimeZone()),
RepeatAfter: 435,
},
},
},
wantCaldavtasks: `BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
X-PUBLISHED-TTL:PT4H
X-WR-CALNAME:test
PRODID:-//RandomProdID which is not random//EN
BEGIN:VTODO
UID:randommduid
DTSTAMP:20181201T011204Z
SUMMARY:Todo #1
DESCRIPTION:Lorem Ipsum
DUE:20181201T011204Z
RRULE:FREQ=SECONDLY;INTERVAL=435
LAST-MODIFIED:00010101T000000Z
LAST-MODIFIED:00010101T000000
END:VTODO
END:VCALENDAR`,
},

View File

@ -42,15 +42,13 @@ func GetCaldavTodosForTasks(list *models.ListWithTasksAndBuckets, listTasks []*m
Description: t.Description,
Completed: t.DoneAt,
// Organizer: &t.CreatedBy, // Disabled until we figure out how this works
Priority: t.Priority,
Start: t.StartDate,
End: t.EndDate,
Created: t.Created,
Updated: t.Updated,
DueDate: t.DueDate,
Duration: duration,
RepeatAfter: t.RepeatAfter,
RepeatMode: t.RepeatMode,
Priority: t.Priority,
Start: t.StartDate,
End: t.EndDate,
Created: t.Created,
Updated: t.Updated,
DueDate: t.DueDate,
Duration: duration,
})
}

View File

@ -18,7 +18,6 @@ package db
import (
"encoding/json"
"strings"
"code.vikunja.io/api/pkg/log"
@ -54,35 +53,7 @@ func Restore(table string, contents []map[string]interface{}) (err error) {
return err
}
meta, err := x.DBMetas()
if err != nil {
return err
}
var metaForCurrentTable *schemas.Table
for _, m := range meta {
if m.Name == table {
metaForCurrentTable = m
break
}
}
if metaForCurrentTable == nil {
log.Fatalf("Could not find table definition for table %s", table)
}
for _, content := range contents {
for colName, value := range content {
// Date fields might get restored as 0001-01-01 from null dates. This can have unintended side-effects like
// users being scheduled for deletion after a restore.
// To avoid this, we set these dates to nil so that they'll end up as null in the db.
col := metaForCurrentTable.GetColumn(colName)
strVal, is := value.(string)
if is && col.SQLType.IsTime() && (strVal == "" || strings.HasPrefix(strVal, "0001-")) {
content[colName] = nil
}
}
if _, err := x.Table(table).Insert(content); err != nil {
return err
}

View File

@ -337,7 +337,6 @@
bucket_id: 20
created: 2018-12-01 01:12:04
updated: 2018-12-01 01:12:04
due_date: 2018-10-30 22:25:24
- id: 37
title: 'task #37'
done: false

View File

@ -85,7 +85,7 @@ func getMessage(opts *Opts) *mail.Msg {
m.Subject(opts.Subject)
for _, h := range opts.Headers {
m.SetGenHeader(h.Field, h.Content)
m.SetHeader(h.Field, h.Content)
}
for name, content := range opts.Embeds {

View File

@ -156,7 +156,7 @@ func GetListsByNamespaceID(s *xorm.Session, nID int64, doer *user.User) (lists [
Alias("l").
Join("LEFT", []string{"namespaces", "n"}, "l.namespace_id = n.id").
Where("l.is_archived = false").
Where("n.is_archived = false OR n.is_archived IS NULL").
Where("n.is_archived = false").
Where("namespace_id = ?", nID).
Find(&lists)
}

View File

@ -37,9 +37,7 @@ func getUndoneOverdueTasks(s *xorm.Session, now time.Time) (usersWithTasks map[i
var tasks []*Task
err = s.
Where("due_date is not null AND due_date < ? AND lists.is_archived = false AND namespaces.is_archived = false", nextMinute.Add(time.Hour*14).Format(dbTimeFormat)).
Join("LEFT", "lists", "lists.id = tasks.list_id").
Join("LEFT", "namespaces", "lists.namespace_id = namespaces.id").
Where("due_date is not null and due_date < ?", nextMinute.Add(time.Hour*14).Format(dbTimeFormat)).
And("done = false").
Find(&tasks)
if err != nil {
@ -140,13 +138,9 @@ func RegisterOverdueReminderCron() {
}
if len(ut.tasks) == 1 {
// We know there's only one entry in the map so this is actually O(1) and we can use it to get the
// first entry without knowing the key of it.
for _, t := range ut.tasks {
n = &UndoneTaskOverdueNotification{
User: ut.user,
Task: t,
}
n = &UndoneTaskOverdueNotification{
User: ut.user,
Task: ut.tasks[0],
}
}

View File

@ -830,11 +830,6 @@ func setTaskBucket(s *xorm.Session, task *Task, originalTask *Task, doCheckBucke
}
}
if task.BucketID == 0 && originalTask != nil && originalTask.BucketID != 0 {
task.BucketID = originalTask.BucketID
}
// Either no bucket was provided or the task was moved between lists
if task.BucketID == 0 || (originalTask != nil && task.ListID != 0 && originalTask.ListID != task.ListID) {
bucket, err = getDefaultBucket(s, task.ListID)
if err != nil {
@ -1031,7 +1026,7 @@ func (t *Task) Update(s *xorm.Session, a web.Auth) (err error) {
// When a repeating task is marked as done, we update all deadlines and reminders and set it as undone
updateDone(&ot, t)
if err := setTaskBucket(s, t, &ot, t.BucketID != 0 && t.BucketID != ot.BucketID); err != nil {
if err := setTaskBucket(s, t, &ot, t.BucketID != ot.BucketID); err != nil {
return err
}
@ -1374,7 +1369,7 @@ func setTaskDatesFromCurrentDateRepeat(oldTask, newTask *Task) {
// This helper function updates the reminders, doneAt, start and end dates of the *old* task
// and saves the new values in the newTask object.
// We make a few assumptions here:
// We make a few assumtions here:
// 1. Everything in oldTask is the truth - we figure out if we update anything at all if oldTask.RepeatAfter has a value > 0
// 2. Because of 1., this functions should not be used to update values other than Done in the same go
func updateDone(oldTask *Task, newTask *Task) {

View File

@ -51,7 +51,6 @@ type Provider struct {
Key string `json:"key"`
OriginalAuthURL string `json:"-"`
AuthURL string `json:"auth_url"`
LogoutURL string `json:"logout_url"`
ClientID string `json:"client_id"`
ClientSecret string `json:"-"`
openIDProvider *oidc.Provider

View File

@ -60,7 +60,6 @@ func GetAllProviders() (providers []*Provider, err error) {
}
provider, err := getProviderFromMap(pi)
if err != nil {
if provider != nil {
log.Errorf("Error while getting openid provider %s: %s", provider.Name, err)
@ -120,18 +119,12 @@ func getProviderFromMap(pi map[string]interface{}) (provider *Provider, err erro
k := getKeyFromName(name)
logoutURL, ok := pi["logouturl"].(string)
if !ok {
logoutURL = ""
}
provider = &Provider{
Name: pi["name"].(string),
Key: k,
AuthURL: pi["authurl"].(string),
OriginalAuthURL: pi["authurl"].(string),
ClientSecret: pi["clientsecret"].(string),
LogoutURL: logoutURL,
}
cl, is := pi["clientid"].(int)
@ -150,6 +143,7 @@ func getProviderFromMap(pi map[string]interface{}) (provider *Provider, err erro
ClientID: provider.ClientID,
ClientSecret: provider.ClientSecret,
RedirectURL: config.AuthOpenIDRedirectURL.GetString() + k,
// Discovery returns the OAuth2 endpoints.
Endpoint: provider.openIDProvider.Endpoint(),

View File

@ -22,7 +22,6 @@ import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"os"
@ -145,16 +144,11 @@ func Restore(filename string) error {
// FIXME: There has to be a general way to do this but this works for now.
if table == "notifications" {
for i := range content {
var decoded []byte
decoded, err = base64.StdEncoding.DecodeString(content[i]["notification"].(string))
if err != nil && !errors.Is(err, base64.CorruptInputError(0)) {
decoded, err := base64.StdEncoding.DecodeString(content[i]["notification"].(string))
if err != nil {
return fmt.Errorf("could not decode notification %s: %w", content[i]["notification"], err)
}
if err != nil && errors.Is(err, base64.CorruptInputError(0)) {
decoded = []byte(content[i]["notification"].(string))
}
content[i]["notification"] = string(decoded)
}
}

View File

@ -45,25 +45,28 @@ type apiTokenResponse struct {
}
type label struct {
ID string `json:"id"`
ID int64 `json:"id"`
Name string `json:"name"`
Color string `json:"color"`
Color int64 `json:"color"`
ItemOrder int64 `json:"item_order"`
IsDeleted bool `json:"is_deleted"`
IsFavorite bool `json:"is_favorite"`
IsDeleted int64 `json:"is_deleted"`
IsFavorite int64 `json:"is_favorite"`
}
type project struct {
ID string `json:"id"`
Name string `json:"name"`
Color string `json:"color"`
ParentID string `json:"parent_id"`
ChildOrder int64 `json:"child_order"`
Collapsed bool `json:"collapsed"`
Shared bool `json:"shared"`
IsDeleted bool `json:"is_deleted"`
IsArchived bool `json:"is_archived"`
IsFavorite bool `json:"is_favorite"`
ID int64 `json:"id"`
LegacyID int64 `json:"legacy_id"`
Name string `json:"name"`
Color int64 `json:"color"`
ParentID int64 `json:"parent_id"`
ChildOrder int64 `json:"child_order"`
Collapsed int64 `json:"collapsed"`
Shared bool `json:"shared"`
LegacyParentID int64 `json:"legacy_parent_id"`
SyncID int64 `json:"sync_id"`
IsDeleted int64 `json:"is_deleted"`
IsArchived int64 `json:"is_archived"`
IsFavorite int64 `json:"is_favorite"`
}
type dueDate struct {
@ -75,26 +78,31 @@ type dueDate struct {
}
type item struct {
ID string `json:"id"`
LegacyID string `json:"legacy_id"`
UserID string `json:"user_id"`
ProjectID string `json:"project_id"`
Content string `json:"content"`
Priority int64 `json:"priority"`
Due *dueDate `json:"due"`
ParentID string `json:"parent_id"`
ChildOrder int64 `json:"child_order"`
SectionID string `json:"section_id"`
Children interface{} `json:"children"`
Labels []string `json:"labels"`
AddedByUID string `json:"added_by_uid"`
AssignedByUID string `json:"assigned_by_uid"`
ResponsibleUID string `json:"responsible_uid"`
Checked bool `json:"checked"`
IsDeleted bool `json:"is_deleted"`
DateAdded time.Time `json:"added_at"`
HasMoreNotes bool `json:"has_more_notes"`
DateCompleted time.Time `json:"completed_at"`
ID int64 `json:"id"`
LegacyID int64 `json:"legacy_id"`
UserID int64 `json:"user_id"`
ProjectID int64 `json:"project_id"`
LegacyProjectID int64 `json:"legacy_project_id"`
Content string `json:"content"`
Priority int64 `json:"priority"`
Due *dueDate `json:"due"`
ParentID int64 `json:"parent_id"`
LegacyParentID int64 `json:"legacy_parent_id"`
ChildOrder int64 `json:"child_order"`
SectionID int64 `json:"section_id"`
DayOrder int64 `json:"day_order"`
Collapsed int64 `json:"collapsed"`
Children interface{} `json:"children"`
Labels []int64 `json:"labels"`
AddedByUID int64 `json:"added_by_uid"`
AssignedByUID int64 `json:"assigned_by_uid"`
ResponsibleUID int64 `json:"responsible_uid"`
Checked int64 `json:"checked"`
InHistory int64 `json:"in_history"`
IsDeleted int64 `json:"is_deleted"`
DateAdded time.Time `json:"date_added"`
HasMoreNotes bool `json:"has_more_notes"`
DateCompleted time.Time `json:"date_completed"`
}
type itemWrapper struct {
@ -102,11 +110,12 @@ type itemWrapper struct {
}
type doneItem struct {
CompletedDate time.Time `json:"completed_at"`
CompletedDate time.Time `json:"completed_date"`
Content string `json:"content"`
ID string `json:"id"`
ProjectID string `json:"project_id"`
TaskID string `json:"task_id"`
ID int64 `json:"id"`
ProjectID int64 `json:"project_id"`
TaskID int64 `json:"task_id"`
UserID int `json:"user_id"`
}
type doneItemSync struct {
@ -123,14 +132,18 @@ type fileAttachment struct {
}
type note struct {
ID string `json:"id"`
PostedUID int64 `json:"posted_uid"`
ProjectID string `json:"project_id"`
ItemID string `json:"item_id"`
Content string `json:"content"`
FileAttachment *fileAttachment `json:"file_attachment"`
IsDeleted bool `json:"is_deleted"`
Posted time.Time `json:"posted_at"`
ID int64 `json:"id"`
LegacyID int64 `json:"legacy_id"`
PostedUID int64 `json:"posted_uid"`
ProjectID int64 `json:"project_id"`
LegacyProjectID int64 `json:"legacy_project_id"`
ItemID int64 `json:"item_id"`
LegacyItemID int64 `json:"legacy_item_id"`
Content string `json:"content"`
FileAttachment *fileAttachment `json:"file_attachment"`
UidsToNotify []int64 `json:"uids_to_notify"`
IsDeleted int64 `json:"is_deleted"`
Posted time.Time `json:"posted"`
}
type projectNote struct {
@ -140,13 +153,15 @@ type projectNote struct {
IsDeleted int64 `json:"is_deleted"`
Posted time.Time `json:"posted"`
PostedUID int64 `json:"posted_uid"`
ProjectID string `json:"project_id"`
ProjectID int64 `json:"project_id"`
UidsToNotify []int64 `json:"uids_to_notify"`
}
type reminder struct {
ID string `json:"id"`
ItemID string `json:"item_id"`
ID int64 `json:"id"`
NotifyUID int64 `json:"notify_uid"`
ItemID int64 `json:"item_id"`
Service string `json:"service"`
Type string `json:"type"`
Due *dueDate `json:"due"`
MmOffset int64 `json:"mm_offset"`
@ -154,11 +169,11 @@ type reminder struct {
}
type section struct {
ID string `json:"id"`
DateAdded time.Time `json:"added_at"`
ID int64 `json:"id"`
DateAdded time.Time `json:"date_added"`
IsDeleted bool `json:"is_deleted"`
Name string `json:"name"`
ProjectID string `json:"project_id"`
ProjectID int64 `json:"project_id"`
SectionOrder int64 `json:"section_order"`
}
@ -172,32 +187,32 @@ type sync struct {
Sections []*section `json:"sections"`
}
var todoistColors = map[string]string{}
var todoistColors = map[int64]string{}
func init() {
todoistColors = make(map[string]string, 19)
// The todoists colors are static, taken from https://developer.todoist.com/guides/#colors
todoistColors = map[string]string{
"berry_red": "b8256f",
"red": "db4035",
"orange": "ff9933",
"yellow": "fad000",
"olive_green": "afb83b",
"lime_green": "7ecc49",
"green": "299438",
"mint_green": "6accbc",
"teal": "158fad",
"sky_blue": "14aaf5",
"light_blue": "96c3eb",
"blue": "4073ff",
"grape": "884dff",
"violet": "af38eb",
"lavender": "eb96eb",
"magenta": "e05194",
"salmon": "ff8d85",
"charcoal": "808080",
"grey": "b8b8b8",
"taupe": "ccac93",
todoistColors = make(map[int64]string, 19)
// The todoists colors are static, taken from https://developer.todoist.com/sync/v8/#colors
todoistColors = map[int64]string{
30: "b8256f",
31: "db4035",
32: "ff9933",
33: "fad000",
34: "afb83b",
35: "7ecc49",
36: "299438",
37: "6accbc",
38: "158fad",
39: "14aaf5",
40: "96c3eb",
41: "4073ff",
42: "884dff",
43: "af38eb",
44: "eb96eb",
45: "e05194",
46: "ff8d85",
47: "808080",
48: "b8b8b8",
49: "ccac93",
}
}
@ -251,7 +266,7 @@ func parseDate(dateString string) (date time.Time, err error) {
return date, err
}
func convertTodoistToVikunja(sync *sync, doneItems map[string]*doneItem) (fullVikunjaHierachie []*models.NamespaceWithListsAndTasks, err error) {
func convertTodoistToVikunja(sync *sync, doneItems map[int64]*doneItem) (fullVikunjaHierachie []*models.NamespaceWithListsAndTasks, err error) {
newNamespace := &models.NamespaceWithListsAndTasks{
Namespace: models.Namespace{
@ -260,22 +275,20 @@ func convertTodoistToVikunja(sync *sync, doneItems map[string]*doneItem) (fullVi
}
// A map for all vikunja lists with the project id they're coming from as key
lists := make(map[string]*models.ListWithTasksAndBuckets, len(sync.Projects))
lists := make(map[int64]*models.ListWithTasksAndBuckets, len(sync.Projects))
// A map for all vikunja tasks with the todoist task id as key to find them easily and add more data
tasks := make(map[string]*models.TaskWithComments, len(sync.Items))
tasks := make(map[int64]*models.TaskWithComments, len(sync.Items))
// A map for all vikunja labels with the todoist id as key to find them easier
labels := make(map[string]*models.Label, len(sync.Labels))
sections := make(map[string]int64)
labels := make(map[int64]*models.Label, len(sync.Labels))
for _, p := range sync.Projects {
list := &models.ListWithTasksAndBuckets{
List: models.List{
Title: p.Name,
HexColor: todoistColors[p.Color],
IsArchived: p.IsArchived,
IsArchived: p.IsArchived == 1,
},
}
@ -288,22 +301,20 @@ func convertTodoistToVikunja(sync *sync, doneItems map[string]*doneItem) (fullVi
return sync.Sections[i].SectionOrder < sync.Sections[j].SectionOrder
})
var fabricatedSectionID int64 = 1
for _, section := range sync.Sections {
if section.IsDeleted || section.ProjectID == "" {
if section.IsDeleted || section.ProjectID == 0 {
continue
}
lists[section.ProjectID].Buckets = append(lists[section.ProjectID].Buckets, &models.Bucket{
ID: fabricatedSectionID,
ID: section.ID,
Title: section.Name,
Created: section.DateAdded,
})
sections[section.ID] = fabricatedSectionID
}
for _, label := range sync.Labels {
labels[label.Name] = &models.Label{
labels[label.ID] = &models.Label{
Title: label.Name,
HexColor: todoistColors[label.Color],
}
@ -314,8 +325,8 @@ func convertTodoistToVikunja(sync *sync, doneItems map[string]*doneItem) (fullVi
Task: models.Task{
Title: i.Content,
Created: i.DateAdded.In(config.GetTimeZone()),
Done: i.Checked,
BucketID: sections[i.SectionID],
Done: i.Checked == 1,
BucketID: i.SectionID,
},
}
@ -346,31 +357,29 @@ func convertTodoistToVikunja(sync *sync, doneItems map[string]*doneItem) (fullVi
}
// Put all labels together from earlier
for _, lName := range i.Labels {
task.Labels = append(task.Labels, labels[lName])
for _, lID := range i.Labels {
task.Labels = append(task.Labels, labels[lID])
}
tasks[i.ID] = task
if _, exists := lists[i.ProjectID]; !exists {
log.Debugf("[Todoist Migration] Tried to put item %s in project %s but the project does not exist", i.ID, i.ProjectID)
log.Debugf("[Todoist Migration] Tried to put item %d in project %d but the project does not exist", i.ID, i.ProjectID)
continue
}
lists[i.ProjectID].Tasks = append(lists[i.ProjectID].Tasks, task)
fabricatedSectionID++
}
// If the parenId of a task is not 0, create a task relation
// We're looping again here to make sure we have seem all tasks before and have them in our map
for _, i := range sync.Items {
if i.ParentID == "" {
if i.ParentID == 0 {
continue
}
if _, exists := tasks[i.ParentID]; !exists {
log.Debugf("[Todoist Migration] Could not find task %s in tasks map while trying to get resolve subtasks for task %s", i.ParentID, i.ID)
log.Debugf("[Todoist Migration] Could not find task %d in tasks map while trying to get resolve subtasks for task %d", i.ParentID, i.ID)
continue
}
@ -398,7 +407,7 @@ func convertTodoistToVikunja(sync *sync, doneItems map[string]*doneItem) (fullVi
// FIXME: Should be comments
for _, n := range sync.Notes {
if _, exists := tasks[n.ItemID]; !exists {
log.Debugf("[Todoist Migration] Could not find task %s for note %s", n.ItemID, n.ID)
log.Debugf("[Todoist Migration] Could not find task %d for note %d", n.ItemID, n.ID)
continue
}
@ -451,7 +460,7 @@ func convertTodoistToVikunja(sync *sync, doneItems map[string]*doneItem) (fullVi
}
if _, exists := tasks[r.ItemID]; !exists {
log.Debugf("Could not find task %s for reminder %s while trying to resolve reminders", r.ItemID, r.ID)
log.Debugf("Could not find task %d for reminder %d while trying to resolve reminders", r.ItemID, r.ID)
continue
}
@ -528,7 +537,7 @@ func (m *Migration) Migrate(u *user.User) (err error) {
"sync_token": []string{"*"},
"resource_types": []string{"[\"all\"]"},
}
resp, err := migration.DoPost("https://api.todoist.com/sync/v9/sync", form)
resp, err := migration.DoPost("https://api.todoist.com/sync/v8/sync", form)
if err != nil {
return
}
@ -544,10 +553,10 @@ func (m *Migration) Migrate(u *user.User) (err error) {
// Get all done tasks and projects
offset := 0
doneItems := make(map[string]*doneItem)
doneItems := make(map[int64]*doneItem)
for {
resp, err = migration.DoPost("https://api.todoist.com/sync/v9/completed/get_all?limit=200&offset="+strconv.Itoa(offset), form)
resp, err = migration.DoPost("https://api.todoist.com/sync/v8/completed/get_all?limit=200&offset="+strconv.Itoa(offset), form)
if err != nil {
return
}
@ -571,9 +580,9 @@ func (m *Migration) Migrate(u *user.User) (err error) {
doneItems[i.TaskID] = i
// need to get done item data
resp, err = migration.DoPost("https://api.todoist.com/sync/v9/items/get", url.Values{
resp, err = migration.DoPost("https://api.todoist.com/sync/v8/items/get", url.Values{
"token": []string{token},
"item_id": []string{i.TaskID},
"item_id": []string{strconv.FormatInt(i.TaskID, 10)},
})
if err != nil {
return
@ -585,7 +594,7 @@ func (m *Migration) Migrate(u *user.User) (err error) {
if err != nil {
return
}
log.Debugf("[Todoist Migration] Retrieved full task data for done task %s", i.TaskID)
log.Debugf("[Todoist Migration] Retrieved full task data for done task %d", i.TaskID)
syncResponse.Items = append(syncResponse.Items, doneI.Item)
}
@ -600,7 +609,7 @@ func (m *Migration) Migrate(u *user.User) (err error) {
log.Debugf("[Todoist Migration] Getting archived projects for user %d", u.ID)
// Get all archived projects
resp, err = migration.DoPost("https://api.todoist.com/sync/v9/projects/get_archived", form)
resp, err = migration.DoPost("https://api.todoist.com/sync/v8/projects/get_archived", form)
if err != nil {
return
}
@ -617,8 +626,9 @@ func (m *Migration) Migrate(u *user.User) (err error) {
log.Debugf("[Todoist Migration] Getting data for archived projects for user %d", u.ID)
// Project data is not included in the regular sync for archived projects so we need to get all of those by hand
//https://api.todoist.com/sync/v8/projects/get_data\?project_id\=2269005399
for _, p := range archivedProjects {
resp, err = migration.DoPost("https://api.todoist.com/sync/v9/projects/get_data?project_id="+p.ID, form)
resp, err = migration.DoPost("https://api.todoist.com/sync/v8/projects/get_data?project_id="+strconv.FormatInt(p.ID, 10), form)
if err != nil {
return
}

View File

@ -18,6 +18,7 @@ package todoist
import (
"os"
"strconv"
"testing"
"time"
@ -49,29 +50,30 @@ func TestConvertTodoistToVikunja(t *testing.T) {
exampleFile, err := os.ReadFile(config.ServiceRootpath.GetString() + "/pkg/modules/migration/wunderlist/testimage.jpg")
assert.NoError(t, err)
makeTestItem := func(id, projectId string, hasDueDate, hasLabels, done bool) *item {
makeTestItem := func(id, projectId int64, hasDueDate, hasLabels, done bool) *item {
item := &item{
ID: id,
UserID: "1855589",
UserID: 1855589,
ProjectID: projectId,
Content: "Task" + id,
Content: "Task" + strconv.FormatInt(id, 10),
Priority: 1,
ParentID: 0,
ChildOrder: 1,
DateAdded: time1,
DateCompleted: nilTime,
}
if done {
item.Checked = true
item.Checked = 1
item.DateCompleted = time3
}
if hasLabels {
item.Labels = []string{
"Label1",
"Label2",
"Label3",
"Label4",
item.Labels = []int64{
80000,
80001,
80002,
80003,
}
}
@ -89,163 +91,163 @@ func TestConvertTodoistToVikunja(t *testing.T) {
testSync := &sync{
Projects: []*project{
{
ID: "396936926",
ID: 396936926,
Name: "Project1",
Color: "berry_red",
Color: 30,
ChildOrder: 1,
Collapsed: false,
Collapsed: 0,
Shared: false,
IsDeleted: false,
IsArchived: false,
IsFavorite: false,
IsDeleted: 0,
IsArchived: 0,
IsFavorite: 0,
},
{
ID: "396936927",
ID: 396936927,
Name: "Project2",
Color: "mint_green",
Color: 37,
ChildOrder: 1,
Collapsed: false,
Collapsed: 0,
Shared: false,
IsDeleted: false,
IsArchived: false,
IsFavorite: false,
IsDeleted: 0,
IsArchived: 0,
IsFavorite: 0,
},
{
ID: "396936928",
ID: 396936928,
Name: "Project3 - Archived",
Color: "mint_green",
Color: 37,
ChildOrder: 1,
Collapsed: false,
Collapsed: 0,
Shared: false,
IsDeleted: false,
IsArchived: true,
IsFavorite: false,
IsDeleted: 0,
IsArchived: 1,
IsFavorite: 0,
},
},
Items: []*item{
makeTestItem("400000000", "396936926", false, false, false),
makeTestItem("400000001", "396936926", false, false, false),
makeTestItem("400000002", "396936926", false, false, false),
makeTestItem("400000003", "396936926", true, true, true),
makeTestItem("400000004", "396936926", false, true, false),
makeTestItem("400000005", "396936926", true, false, true),
makeTestItem("400000006", "396936926", true, false, true),
makeTestItem(400000000, 396936926, false, false, false),
makeTestItem(400000001, 396936926, false, false, false),
makeTestItem(400000002, 396936926, false, false, false),
makeTestItem(400000003, 396936926, true, true, true),
makeTestItem(400000004, 396936926, false, true, false),
makeTestItem(400000005, 396936926, true, false, true),
makeTestItem(400000006, 396936926, true, false, true),
{
ID: "400000110",
UserID: "1855589",
ProjectID: "396936926",
ID: 400000110,
UserID: 1855589,
ProjectID: 396936926,
Content: "Task with parent",
Priority: 2,
ParentID: "400000006",
ParentID: 400000006,
ChildOrder: 1,
Checked: false,
Checked: 0,
DateAdded: time1,
},
{
ID: "400000106",
UserID: "1855589",
ProjectID: "396936926",
ID: 400000106,
UserID: 1855589,
ProjectID: 396936926,
Content: "Task400000106",
Priority: 1,
ParentID: "",
ParentID: 0,
ChildOrder: 1,
DateAdded: time1,
Checked: true,
Checked: 1,
DateCompleted: time3,
Due: &dueDate{
Date: "2021-01-31T19:00:00Z",
Timezone: nil,
IsRecurring: false,
},
Labels: []string{
"Label1",
"Label2",
"Label3",
"Label4",
Labels: []int64{
80000,
80001,
80002,
80003,
},
},
makeTestItem("400000107", "396936926", false, false, true),
makeTestItem("400000108", "396936926", false, false, true),
makeTestItem(400000107, 396936926, false, false, true),
makeTestItem(400000108, 396936926, false, false, true),
{
ID: "400000109",
UserID: "1855589",
ProjectID: "396936926",
ID: 400000109,
UserID: 1855589,
ProjectID: 396936926,
Content: "Task400000109",
Priority: 1,
ChildOrder: 1,
Checked: true,
Checked: 1,
DateAdded: time1,
DateCompleted: time3,
SectionID: "1234",
SectionID: 1234,
},
makeTestItem("400000007", "396936927", true, false, false),
makeTestItem("400000008", "396936927", true, false, false),
makeTestItem("400000009", "396936927", false, false, false),
makeTestItem("400000010", "396936927", false, false, true),
makeTestItem("400000101", "396936927", false, false, false),
makeTestItem("400000102", "396936927", true, true, false),
makeTestItem("400000103", "396936927", false, true, false),
makeTestItem("400000104", "396936927", false, true, false),
makeTestItem("400000105", "396936927", true, true, false),
makeTestItem(400000007, 396936927, true, false, false),
makeTestItem(400000008, 396936927, true, false, false),
makeTestItem(400000009, 396936927, false, false, false),
makeTestItem(400000010, 396936927, false, false, true),
makeTestItem(400000101, 396936927, false, false, false),
makeTestItem(400000102, 396936927, true, true, false),
makeTestItem(400000103, 396936927, false, true, false),
makeTestItem(400000104, 396936927, false, true, false),
makeTestItem(400000105, 396936927, true, true, false),
makeTestItem("400000111", "396936928", false, false, true),
makeTestItem(400000111, 396936928, false, false, true),
},
Labels: []*label{
{
ID: "80000",
ID: 80000,
Name: "Label1",
Color: "berry_red",
Color: 30,
},
{
ID: "80001",
ID: 80001,
Name: "Label2",
Color: "red",
Color: 31,
},
{
ID: "80002",
ID: 80002,
Name: "Label3",
Color: "orange",
Color: 32,
},
{
ID: "80003",
ID: 80003,
Name: "Label4",
Color: "yellow",
Color: 33,
},
},
Notes: []*note{
{
ID: "101476",
ID: 101476,
PostedUID: 1855589,
ItemID: "400000000",
ItemID: 400000000,
Content: "Lorem Ipsum dolor sit amet",
Posted: time1,
},
{
ID: "101477",
ID: 101477,
PostedUID: 1855589,
ItemID: "400000001",
ItemID: 400000001,
Content: "Lorem Ipsum dolor sit amet",
Posted: time1,
},
{
ID: "101478",
ID: 101478,
PostedUID: 1855589,
ItemID: "400000003",
ItemID: 400000003,
Content: "Lorem Ipsum dolor sit amet",
Posted: time1,
},
{
ID: "101479",
ID: 101479,
PostedUID: 1855589,
ItemID: "400000010",
ItemID: 400000010,
Content: "Lorem Ipsum dolor sit amet",
Posted: time1,
},
{
ID: "101480",
ID: 101480,
PostedUID: 1855589,
ItemID: "400000101",
ItemID: 400000101,
Content: "Lorem Ipsum dolor sit amet",
FileAttachment: &fileAttachment{
FileName: "file.md",
@ -261,43 +263,43 @@ func TestConvertTodoistToVikunja(t *testing.T) {
{
ID: 102000,
Content: "Lorem Ipsum dolor sit amet",
ProjectID: "396936926",
ProjectID: 396936926,
Posted: time3,
PostedUID: 1855589,
},
{
ID: 102001,
Content: "Lorem Ipsum dolor sit amet 2",
ProjectID: "396936926",
ProjectID: 396936926,
Posted: time3,
PostedUID: 1855589,
},
{
ID: 102002,
Content: "Lorem Ipsum dolor sit amet 3",
ProjectID: "396936926",
ProjectID: 396936926,
Posted: time3,
PostedUID: 1855589,
},
{
ID: 102003,
Content: "Lorem Ipsum dolor sit amet 4",
ProjectID: "396936927",
ProjectID: 396936927,
Posted: time3,
PostedUID: 1855589,
},
{
ID: 102004,
Content: "Lorem Ipsum dolor sit amet 5",
ProjectID: "396936927",
ProjectID: 396936927,
Posted: time3,
PostedUID: 1855589,
},
},
Reminders: []*reminder{
{
ID: "103000",
ItemID: "400000000",
ID: 103000,
ItemID: 400000000,
Due: &dueDate{
Date: "2020-06-15",
IsRecurring: false,
@ -305,40 +307,40 @@ func TestConvertTodoistToVikunja(t *testing.T) {
MmOffset: 180,
},
{
ID: "103001",
ItemID: "400000000",
ID: 103001,
ItemID: 400000000,
Due: &dueDate{
Date: "2020-06-16T07:00:00",
IsRecurring: false,
},
},
{
ID: "103002",
ItemID: "400000002",
ID: 103002,
ItemID: 400000002,
Due: &dueDate{
Date: "2020-07-15T07:00:00Z",
IsRecurring: true,
},
},
{
ID: "103003",
ItemID: "400000003",
ID: 103003,
ItemID: 400000003,
Due: &dueDate{
Date: "2020-06-15T07:00:00",
IsRecurring: false,
},
},
{
ID: "103004",
ItemID: "400000005",
ID: 103004,
ItemID: 400000005,
Due: &dueDate{
Date: "2020-06-15T07:00:00",
IsRecurring: false,
},
},
{
ID: "103006",
ItemID: "400000009",
ID: 103006,
ItemID: 400000009,
Due: &dueDate{
Date: "2020-06-15T07:00:00",
IsRecurring: false,
@ -347,9 +349,9 @@ func TestConvertTodoistToVikunja(t *testing.T) {
},
Sections: []*section{
{
ID: "1234",
ID: 1234,
Name: "Some Bucket",
ProjectID: "396936926",
ProjectID: 396936926,
},
},
}
@ -357,19 +359,19 @@ func TestConvertTodoistToVikunja(t *testing.T) {
vikunjaLabels := []*models.Label{
{
Title: "Label1",
HexColor: todoistColors["berry_red"],
HexColor: todoistColors[30],
},
{
Title: "Label2",
HexColor: todoistColors["red"],
HexColor: todoistColors[31],
},
{
Title: "Label3",
HexColor: todoistColors["orange"],
HexColor: todoistColors[32],
},
{
Title: "Label4",
HexColor: todoistColors["yellow"],
HexColor: todoistColors[33],
},
}
@ -383,11 +385,11 @@ func TestConvertTodoistToVikunja(t *testing.T) {
List: models.List{
Title: "Project1",
Description: "Lorem Ipsum dolor sit amet\nLorem Ipsum dolor sit amet 2\nLorem Ipsum dolor sit amet 3",
HexColor: todoistColors["berry_red"],
HexColor: todoistColors[30],
},
Buckets: []*models.Bucket{
{
ID: 1,
ID: 1234,
Title: "Some Bucket",
},
},
@ -508,7 +510,7 @@ func TestConvertTodoistToVikunja(t *testing.T) {
Done: true,
Created: time1,
DoneAt: time3,
BucketID: 1,
BucketID: 1234,
},
},
},
@ -517,7 +519,7 @@ func TestConvertTodoistToVikunja(t *testing.T) {
List: models.List{
Title: "Project2",
Description: "Lorem Ipsum dolor sit amet 4\nLorem Ipsum dolor sit amet 5",
HexColor: todoistColors["mint_green"],
HexColor: todoistColors[37],
},
Tasks: []*models.TaskWithComments{
{
@ -614,7 +616,7 @@ func TestConvertTodoistToVikunja(t *testing.T) {
{
List: models.List{
Title: "Project3 - Archived",
HexColor: todoistColors["mint_green"],
HexColor: todoistColors[37],
IsArchived: true,
},
Tasks: []*models.TaskWithComments{
@ -632,7 +634,7 @@ func TestConvertTodoistToVikunja(t *testing.T) {
},
}
doneItems := make(map[string]*doneItem)
doneItems := make(map[int64]*doneItem)
hierachie, err := convertTodoistToVikunja(testSync, doneItems)
assert.NoError(t, err)
assert.NotNil(t, hierachie)

View File

@ -48,6 +48,7 @@ package routes
import (
"errors"
"fmt"
"net/url"
"strings"
"time"
@ -79,7 +80,7 @@ import (
"github.com/getsentry/sentry-go"
sentryecho "github.com/getsentry/sentry-go/echo"
echojwt "github.com/labstack/echo-jwt/v4"
"github.com/golang-jwt/jwt/v4"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
elog "github.com/labstack/gommon/log"
@ -272,8 +273,29 @@ func registerAPIRoutes(a *echo.Group) {
ur.POST("/shares/:share/auth", apiv1.AuthenticateLinkShare)
}
// ===== Routes with Authentication =====
a.Use(echojwt.JWT([]byte(config.ServiceJWTSecret.GetString())))
// ===== Routes with Authetication =====
// Authetification
a.Use(middleware.JWTWithConfig(middleware.JWTConfig{
// Custom parse function to make the middleware work with the github.com/golang-jwt/jwt/v4 package.
// See https://github.com/labstack/echo/pull/1916#issuecomment-878046299
ParseTokenFunc: func(auth string, c echo.Context) (interface{}, error) {
keyFunc := func(t *jwt.Token) (interface{}, error) {
if t.Method.Alg() != "HS256" {
return nil, fmt.Errorf("unexpected jwt signing method=%v", t.Header["alg"])
}
return []byte(config.ServiceJWTSecret.GetString()), nil
}
token, err := jwt.Parse(auth, keyFunc)
if err != nil {
return nil, err
}
if !token.Valid {
return nil, errors.New("invalid token")
}
return token, nil
},
}))
// Rate limit
setupRateLimit(a, config.RateLimitKind.GetString())

View File

@ -7727,11 +7727,36 @@ const docTemplate = `{
},
"created_by": {
"description": "The user who initially created the bucket.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"filter_by": {
"description": "The field name of the field to filter by",
"type": "array",
"items": {
"type": "string"
}
},
"filter_comparator": {
"description": "The comparator for field and value",
"type": "array",
"items": {
"type": "string"
}
},
"filter_concat": {
"description": "The way all filter conditions are concatenated together, can be either \"and\" or \"or\".,",
"type": "string"
},
"filter_include_nulls": {
"description": "If set to true, the result will also include null values",
"type": "boolean"
},
"filter_value": {
"description": "The value of the field name to filter by",
"type": "array",
"items": {
"type": "string"
}
},
"id": {
"description": "The unique, numeric id of this bucket.",
@ -7750,10 +7775,24 @@ const docTemplate = `{
"description": "The list this bucket belongs to.",
"type": "integer"
},
"order_by": {
"description": "The query parameter to order the items by. This can be either asc or desc, with asc being the default.",
"type": "array",
"items": {
"type": "string"
}
},
"position": {
"description": "The position this bucket has when querying all buckets. See the tasks.position property on how to use this.",
"type": "number"
},
"sort_by": {
"description": "The query parameter to sort by. This is for ex. done, priority, etc.",
"type": "array",
"items": {
"type": "string"
}
},
"tasks": {
"description": "All tasks which belong to this bucket.",
"type": "array",
@ -7769,7 +7808,9 @@ const docTemplate = `{
"updated": {
"description": "A timestamp when this bucket was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.BulkAssignees": {
@ -7781,7 +7822,9 @@ const docTemplate = `{
"items": {
"$ref": "#/definitions/user.User"
}
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.BulkTask": {
@ -7815,11 +7858,7 @@ const docTemplate = `{
},
"created_by": {
"description": "The user who initially created the task.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"description": {
"description": "The task description.",
@ -7891,11 +7930,7 @@ const docTemplate = `{
},
"related_tasks": {
"description": "All related tasks, grouped by their relation kind",
"allOf": [
{
"$ref": "#/definitions/models.RelatedTaskMap"
}
]
"$ref": "#/definitions/models.RelatedTaskMap"
},
"reminder_dates": {
"description": "An array of datetimes when the user wants to be reminded of the task.",
@ -7910,11 +7945,7 @@ const docTemplate = `{
},
"repeat_mode": {
"description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.",
"allOf": [
{
"$ref": "#/definitions/models.TaskRepeatMode"
}
]
"type": "integer"
},
"start_date": {
"description": "When this task starts.",
@ -7922,11 +7953,7 @@ const docTemplate = `{
},
"subscription": {
"description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.",
"allOf": [
{
"$ref": "#/definitions/models.Subscription"
}
]
"$ref": "#/definitions/models.Subscription"
},
"task_ids": {
"description": "A list of task ids to update",
@ -7943,7 +7970,9 @@ const docTemplate = `{
"updated": {
"description": "A timestamp when this task was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.DatabaseNotifications": {
@ -7971,7 +8000,9 @@ const docTemplate = `{
"read_at": {
"description": "When this notification is marked as read, this will be updated with the current timestamp.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.Label": {
@ -7983,11 +8014,7 @@ const docTemplate = `{
},
"created_by": {
"description": "The user who created this label",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"description": {
"description": "The label description.",
@ -8011,7 +8038,9 @@ const docTemplate = `{
"updated": {
"description": "A timestamp when this label was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.LabelTask": {
@ -8024,7 +8053,9 @@ const docTemplate = `{
"label_id": {
"description": "The label id you want to associate with a task.",
"type": "integer"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.LabelTaskBulk": {
@ -8036,7 +8067,9 @@ const docTemplate = `{
"items": {
"$ref": "#/definitions/models.Label"
}
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.LinkSharing": {
@ -8064,36 +8097,26 @@ const docTemplate = `{
},
"right": {
"description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.Right"
}
]
"maximum": 2
},
"shared_by": {
"description": "The user who shared this list",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"sharing_type": {
"description": "The kind of this link. 0 = undefined, 1 = without password, 2 = with password.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.SharingType"
}
]
"maximum": 2
},
"updated": {
"description": "A timestamp when this share was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.List": {
@ -8142,11 +8165,7 @@ const docTemplate = `{
},
"owner": {
"description": "The user who created this list.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"position": {
"description": "The position this list has when querying all lists. See the tasks.position property on how to use this.",
@ -8154,11 +8173,7 @@ const docTemplate = `{
},
"subscription": {
"description": "The subscription status for the user reading this list. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one list.",
"allOf": [
{
"$ref": "#/definitions/models.Subscription"
}
]
"$ref": "#/definitions/models.Subscription"
},
"title": {
"description": "The title of the list. You'll see this in the namespace overview.",
@ -8169,7 +8184,9 @@ const docTemplate = `{
"updated": {
"description": "A timestamp when this list was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.ListDuplicate": {
@ -8177,16 +8194,14 @@ const docTemplate = `{
"properties": {
"list": {
"description": "The copied list",
"allOf": [
{
"$ref": "#/definitions/models.List"
}
]
"$ref": "#/definitions/models.List"
},
"namespace_id": {
"description": "The target namespace ID",
"type": "integer"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.ListUser": {
@ -8202,13 +8217,9 @@ const docTemplate = `{
},
"right": {
"description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.Right"
}
]
"maximum": 2
},
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
@ -8217,7 +8228,9 @@ const docTemplate = `{
"user_id": {
"description": "The username.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.Message": {
@ -8255,19 +8268,11 @@ const docTemplate = `{
},
"owner": {
"description": "The user who owns this namespace",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"subscription": {
"description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.",
"allOf": [
{
"$ref": "#/definitions/models.Subscription"
}
]
"$ref": "#/definitions/models.Subscription"
},
"title": {
"description": "The name of this namespace.",
@ -8278,7 +8283,9 @@ const docTemplate = `{
"updated": {
"description": "A timestamp when this namespace was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.NamespaceUser": {
@ -8294,13 +8301,9 @@ const docTemplate = `{
},
"right": {
"description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.Right"
}
]
"maximum": 2
},
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
@ -8309,7 +8312,9 @@ const docTemplate = `{
"user_id": {
"description": "The username.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.NamespaceWithLists": {
@ -8344,19 +8349,11 @@ const docTemplate = `{
},
"owner": {
"description": "The user who owns this namespace",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"subscription": {
"description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.",
"allOf": [
{
"$ref": "#/definitions/models.Subscription"
}
]
"$ref": "#/definitions/models.Subscription"
},
"title": {
"description": "The name of this namespace.",
@ -8367,7 +8364,9 @@ const docTemplate = `{
"updated": {
"description": "A timestamp when this namespace was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.RelatedTaskMap": {
@ -8379,50 +8378,6 @@ const docTemplate = `{
}
}
},
"models.RelationKind": {
"type": "string",
"enum": [
"unknown",
"subtask",
"parenttask",
"related",
"duplicateof",
"duplicates",
"blocking",
"blocked",
"precedes",
"follows",
"copiedfrom",
"copiedto"
],
"x-enum-varnames": [
"RelationKindUnknown",
"RelationKindSubtask",
"RelationKindParenttask",
"RelationKindRelated",
"RelationKindDuplicateOf",
"RelationKindDuplicates",
"RelationKindBlocking",
"RelationKindBlocked",
"RelationKindPreceeds",
"RelationKindFollows",
"RelationKindCopiedFrom",
"RelationKindCopiedTo"
]
},
"models.Right": {
"type": "integer",
"enum": [
0,
1,
2
],
"x-enum-varnames": [
"RightRead",
"RightWrite",
"RightAdmin"
]
},
"models.SavedFilter": {
"type": "object",
"properties": {
@ -8436,11 +8391,7 @@ const docTemplate = `{
},
"filters": {
"description": "The actual filters this filter contains",
"allOf": [
{
"$ref": "#/definitions/models.TaskCollection"
}
]
"$ref": "#/definitions/models.TaskCollection"
},
"id": {
"description": "The unique numeric id of this saved filter",
@ -8452,11 +8403,7 @@ const docTemplate = `{
},
"owner": {
"description": "The user who owns this filter",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"title": {
"description": "The title of the filter.",
@ -8467,22 +8414,11 @@ const docTemplate = `{
"updated": {
"description": "A timestamp when this filter was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.SharingType": {
"type": "integer",
"enum": [
0,
1,
2
],
"x-enum-varnames": [
"SharingTypeUnknown",
"SharingTypeWithoutPassword",
"SharingTypeWithPassword"
]
},
"models.Subscription": {
"type": "object",
"properties": {
@ -8503,12 +8439,10 @@ const docTemplate = `{
},
"user": {
"description": "The user who made this subscription",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
}
"$ref": "#/definitions/user.User"
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.Task": {
@ -8542,11 +8476,7 @@ const docTemplate = `{
},
"created_by": {
"description": "The user who initially created the task.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"description": {
"description": "The task description.",
@ -8618,11 +8548,7 @@ const docTemplate = `{
},
"related_tasks": {
"description": "All related tasks, grouped by their relation kind",
"allOf": [
{
"$ref": "#/definitions/models.RelatedTaskMap"
}
]
"$ref": "#/definitions/models.RelatedTaskMap"
},
"reminder_dates": {
"description": "An array of datetimes when the user wants to be reminded of the task.",
@ -8637,11 +8563,7 @@ const docTemplate = `{
},
"repeat_mode": {
"description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.",
"allOf": [
{
"$ref": "#/definitions/models.TaskRepeatMode"
}
]
"type": "integer"
},
"start_date": {
"description": "When this task starts.",
@ -8649,11 +8571,7 @@ const docTemplate = `{
},
"subscription": {
"description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.",
"allOf": [
{
"$ref": "#/definitions/models.Subscription"
}
]
"$ref": "#/definitions/models.Subscription"
},
"title": {
"description": "The task text. This is what you'll see in the list.",
@ -8663,7 +8581,9 @@ const docTemplate = `{
"updated": {
"description": "A timestamp when this task was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskAssginee": {
@ -8674,7 +8594,9 @@ const docTemplate = `{
},
"user_id": {
"type": "integer"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskAttachment": {
@ -8694,7 +8616,9 @@ const docTemplate = `{
},
"task_id": {
"type": "integer"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskCollection": {
@ -8742,7 +8666,9 @@ const docTemplate = `{
"items": {
"type": "string"
}
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskComment": {
@ -8762,7 +8688,9 @@ const docTemplate = `{
},
"updated": {
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskRelation": {
@ -8774,11 +8702,7 @@ const docTemplate = `{
},
"created_by": {
"description": "The user who created this relation",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"other_task_id": {
"description": "The ID of the other task, the task which is being related.",
@ -8786,31 +8710,16 @@ const docTemplate = `{
},
"relation_kind": {
"description": "The kind of the relation.",
"allOf": [
{
"$ref": "#/definitions/models.RelationKind"
}
]
"type": "string"
},
"task_id": {
"description": "The ID of the \"base\" task, the task which has a relation to another.",
"type": "integer"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskRepeatMode": {
"type": "integer",
"enum": [
0,
1,
2
],
"x-enum-varnames": [
"TaskRepeatModeDefault",
"TaskRepeatModeMonth",
"TaskRepeatModeFromCurrentDate"
]
},
"models.Team": {
"type": "object",
"properties": {
@ -8820,11 +8729,7 @@ const docTemplate = `{
},
"created_by": {
"description": "The user who created this team.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"description": {
"description": "The team's description.",
@ -8850,7 +8755,9 @@ const docTemplate = `{
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TeamList": {
@ -8866,13 +8773,9 @@ const docTemplate = `{
},
"right": {
"description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.Right"
}
]
"maximum": 2
},
"team_id": {
"description": "The team id.",
@ -8881,7 +8784,9 @@ const docTemplate = `{
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TeamMember": {
@ -8902,7 +8807,9 @@ const docTemplate = `{
"username": {
"description": "The username of the member. We use this to prevent automated user id entering.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TeamNamespace": {
@ -8918,13 +8825,9 @@ const docTemplate = `{
},
"right": {
"description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.Right"
}
]
"maximum": 2
},
"team_id": {
"description": "The team id.",
@ -8933,7 +8836,9 @@ const docTemplate = `{
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TeamUser": {
@ -8969,7 +8874,8 @@ const docTemplate = `{
"type": "string",
"maxLength": 250,
"minLength": 1
}
},
"web.Auth": {}
}
},
"models.TeamWithRight": {
@ -8981,11 +8887,7 @@ const docTemplate = `{
},
"created_by": {
"description": "The user who created this team.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"description": {
"description": "The team's description.",
@ -9009,12 +8911,16 @@ const docTemplate = `{
"minLength": 1
},
"right": {
"$ref": "#/definitions/models.Right"
"description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0
},
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.UserWithRight": {
@ -9038,7 +8944,9 @@ const docTemplate = `{
"type": "string"
},
"right": {
"$ref": "#/definitions/models.Right"
"description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0
},
"updated": {
"description": "A timestamp when this task was last updated. You cannot change this value.",
@ -9049,7 +8957,8 @@ const docTemplate = `{
"type": "string",
"maxLength": 250,
"minLength": 1
}
},
"web.Auth": {}
}
},
"notifications.DatabaseNotification": {
@ -9099,9 +9008,6 @@ const docTemplate = `{
"key": {
"type": "string"
},
"logout_url": {
"type": "string"
},
"name": {
"type": "string"
}
@ -9281,7 +9187,8 @@ const docTemplate = `{
"type": "string",
"maxLength": 250,
"minLength": 1
}
},
"web.Auth": {}
}
},
"v1.LinkShareAuth": {

View File

@ -7718,11 +7718,36 @@
},
"created_by": {
"description": "The user who initially created the bucket.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"filter_by": {
"description": "The field name of the field to filter by",
"type": "array",
"items": {
"type": "string"
}
},
"filter_comparator": {
"description": "The comparator for field and value",
"type": "array",
"items": {
"type": "string"
}
},
"filter_concat": {
"description": "The way all filter conditions are concatenated together, can be either \"and\" or \"or\".,",
"type": "string"
},
"filter_include_nulls": {
"description": "If set to true, the result will also include null values",
"type": "boolean"
},
"filter_value": {
"description": "The value of the field name to filter by",
"type": "array",
"items": {
"type": "string"
}
},
"id": {
"description": "The unique, numeric id of this bucket.",
@ -7741,10 +7766,24 @@
"description": "The list this bucket belongs to.",
"type": "integer"
},
"order_by": {
"description": "The query parameter to order the items by. This can be either asc or desc, with asc being the default.",
"type": "array",
"items": {
"type": "string"
}
},
"position": {
"description": "The position this bucket has when querying all buckets. See the tasks.position property on how to use this.",
"type": "number"
},
"sort_by": {
"description": "The query parameter to sort by. This is for ex. done, priority, etc.",
"type": "array",
"items": {
"type": "string"
}
},
"tasks": {
"description": "All tasks which belong to this bucket.",
"type": "array",
@ -7760,7 +7799,9 @@
"updated": {
"description": "A timestamp when this bucket was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.BulkAssignees": {
@ -7772,7 +7813,9 @@
"items": {
"$ref": "#/definitions/user.User"
}
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.BulkTask": {
@ -7806,11 +7849,7 @@
},
"created_by": {
"description": "The user who initially created the task.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"description": {
"description": "The task description.",
@ -7882,11 +7921,7 @@
},
"related_tasks": {
"description": "All related tasks, grouped by their relation kind",
"allOf": [
{
"$ref": "#/definitions/models.RelatedTaskMap"
}
]
"$ref": "#/definitions/models.RelatedTaskMap"
},
"reminder_dates": {
"description": "An array of datetimes when the user wants to be reminded of the task.",
@ -7901,11 +7936,7 @@
},
"repeat_mode": {
"description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.",
"allOf": [
{
"$ref": "#/definitions/models.TaskRepeatMode"
}
]
"type": "integer"
},
"start_date": {
"description": "When this task starts.",
@ -7913,11 +7944,7 @@
},
"subscription": {
"description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.",
"allOf": [
{
"$ref": "#/definitions/models.Subscription"
}
]
"$ref": "#/definitions/models.Subscription"
},
"task_ids": {
"description": "A list of task ids to update",
@ -7934,7 +7961,9 @@
"updated": {
"description": "A timestamp when this task was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.DatabaseNotifications": {
@ -7962,7 +7991,9 @@
"read_at": {
"description": "When this notification is marked as read, this will be updated with the current timestamp.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.Label": {
@ -7974,11 +8005,7 @@
},
"created_by": {
"description": "The user who created this label",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"description": {
"description": "The label description.",
@ -8002,7 +8029,9 @@
"updated": {
"description": "A timestamp when this label was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.LabelTask": {
@ -8015,7 +8044,9 @@
"label_id": {
"description": "The label id you want to associate with a task.",
"type": "integer"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.LabelTaskBulk": {
@ -8027,7 +8058,9 @@
"items": {
"$ref": "#/definitions/models.Label"
}
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.LinkSharing": {
@ -8055,36 +8088,26 @@
},
"right": {
"description": "The right this list is shared with. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.Right"
}
]
"maximum": 2
},
"shared_by": {
"description": "The user who shared this list",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"sharing_type": {
"description": "The kind of this link. 0 = undefined, 1 = without password, 2 = with password.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.SharingType"
}
]
"maximum": 2
},
"updated": {
"description": "A timestamp when this share was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.List": {
@ -8133,11 +8156,7 @@
},
"owner": {
"description": "The user who created this list.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"position": {
"description": "The position this list has when querying all lists. See the tasks.position property on how to use this.",
@ -8145,11 +8164,7 @@
},
"subscription": {
"description": "The subscription status for the user reading this list. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one list.",
"allOf": [
{
"$ref": "#/definitions/models.Subscription"
}
]
"$ref": "#/definitions/models.Subscription"
},
"title": {
"description": "The title of the list. You'll see this in the namespace overview.",
@ -8160,7 +8175,9 @@
"updated": {
"description": "A timestamp when this list was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.ListDuplicate": {
@ -8168,16 +8185,14 @@
"properties": {
"list": {
"description": "The copied list",
"allOf": [
{
"$ref": "#/definitions/models.List"
}
]
"$ref": "#/definitions/models.List"
},
"namespace_id": {
"description": "The target namespace ID",
"type": "integer"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.ListUser": {
@ -8193,13 +8208,9 @@
},
"right": {
"description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.Right"
}
]
"maximum": 2
},
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
@ -8208,7 +8219,9 @@
"user_id": {
"description": "The username.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.Message": {
@ -8246,19 +8259,11 @@
},
"owner": {
"description": "The user who owns this namespace",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"subscription": {
"description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.",
"allOf": [
{
"$ref": "#/definitions/models.Subscription"
}
]
"$ref": "#/definitions/models.Subscription"
},
"title": {
"description": "The name of this namespace.",
@ -8269,7 +8274,9 @@
"updated": {
"description": "A timestamp when this namespace was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.NamespaceUser": {
@ -8285,13 +8292,9 @@
},
"right": {
"description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.Right"
}
]
"maximum": 2
},
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
@ -8300,7 +8303,9 @@
"user_id": {
"description": "The username.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.NamespaceWithLists": {
@ -8335,19 +8340,11 @@
},
"owner": {
"description": "The user who owns this namespace",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"subscription": {
"description": "The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one namespace.",
"allOf": [
{
"$ref": "#/definitions/models.Subscription"
}
]
"$ref": "#/definitions/models.Subscription"
},
"title": {
"description": "The name of this namespace.",
@ -8358,7 +8355,9 @@
"updated": {
"description": "A timestamp when this namespace was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.RelatedTaskMap": {
@ -8370,50 +8369,6 @@
}
}
},
"models.RelationKind": {
"type": "string",
"enum": [
"unknown",
"subtask",
"parenttask",
"related",
"duplicateof",
"duplicates",
"blocking",
"blocked",
"precedes",
"follows",
"copiedfrom",
"copiedto"
],
"x-enum-varnames": [
"RelationKindUnknown",
"RelationKindSubtask",
"RelationKindParenttask",
"RelationKindRelated",
"RelationKindDuplicateOf",
"RelationKindDuplicates",
"RelationKindBlocking",
"RelationKindBlocked",
"RelationKindPreceeds",
"RelationKindFollows",
"RelationKindCopiedFrom",
"RelationKindCopiedTo"
]
},
"models.Right": {
"type": "integer",
"enum": [
0,
1,
2
],
"x-enum-varnames": [
"RightRead",
"RightWrite",
"RightAdmin"
]
},
"models.SavedFilter": {
"type": "object",
"properties": {
@ -8427,11 +8382,7 @@
},
"filters": {
"description": "The actual filters this filter contains",
"allOf": [
{
"$ref": "#/definitions/models.TaskCollection"
}
]
"$ref": "#/definitions/models.TaskCollection"
},
"id": {
"description": "The unique numeric id of this saved filter",
@ -8443,11 +8394,7 @@
},
"owner": {
"description": "The user who owns this filter",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"title": {
"description": "The title of the filter.",
@ -8458,22 +8405,11 @@
"updated": {
"description": "A timestamp when this filter was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.SharingType": {
"type": "integer",
"enum": [
0,
1,
2
],
"x-enum-varnames": [
"SharingTypeUnknown",
"SharingTypeWithoutPassword",
"SharingTypeWithPassword"
]
},
"models.Subscription": {
"type": "object",
"properties": {
@ -8494,12 +8430,10 @@
},
"user": {
"description": "The user who made this subscription",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
}
"$ref": "#/definitions/user.User"
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.Task": {
@ -8533,11 +8467,7 @@
},
"created_by": {
"description": "The user who initially created the task.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"description": {
"description": "The task description.",
@ -8609,11 +8539,7 @@
},
"related_tasks": {
"description": "All related tasks, grouped by their relation kind",
"allOf": [
{
"$ref": "#/definitions/models.RelatedTaskMap"
}
]
"$ref": "#/definitions/models.RelatedTaskMap"
},
"reminder_dates": {
"description": "An array of datetimes when the user wants to be reminded of the task.",
@ -8628,11 +8554,7 @@
},
"repeat_mode": {
"description": "Can have three possible values which will trigger when the task is marked as done: 0 = repeats after the amount specified in repeat_after, 1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from the current date rather than the last set date.",
"allOf": [
{
"$ref": "#/definitions/models.TaskRepeatMode"
}
]
"type": "integer"
},
"start_date": {
"description": "When this task starts.",
@ -8640,11 +8562,7 @@
},
"subscription": {
"description": "The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.\nWill only returned when retreiving one task.",
"allOf": [
{
"$ref": "#/definitions/models.Subscription"
}
]
"$ref": "#/definitions/models.Subscription"
},
"title": {
"description": "The task text. This is what you'll see in the list.",
@ -8654,7 +8572,9 @@
"updated": {
"description": "A timestamp when this task was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskAssginee": {
@ -8665,7 +8585,9 @@
},
"user_id": {
"type": "integer"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskAttachment": {
@ -8685,7 +8607,9 @@
},
"task_id": {
"type": "integer"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskCollection": {
@ -8733,7 +8657,9 @@
"items": {
"type": "string"
}
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskComment": {
@ -8753,7 +8679,9 @@
},
"updated": {
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskRelation": {
@ -8765,11 +8693,7 @@
},
"created_by": {
"description": "The user who created this relation",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"other_task_id": {
"description": "The ID of the other task, the task which is being related.",
@ -8777,31 +8701,16 @@
},
"relation_kind": {
"description": "The kind of the relation.",
"allOf": [
{
"$ref": "#/definitions/models.RelationKind"
}
]
"type": "string"
},
"task_id": {
"description": "The ID of the \"base\" task, the task which has a relation to another.",
"type": "integer"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TaskRepeatMode": {
"type": "integer",
"enum": [
0,
1,
2
],
"x-enum-varnames": [
"TaskRepeatModeDefault",
"TaskRepeatModeMonth",
"TaskRepeatModeFromCurrentDate"
]
},
"models.Team": {
"type": "object",
"properties": {
@ -8811,11 +8720,7 @@
},
"created_by": {
"description": "The user who created this team.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"description": {
"description": "The team's description.",
@ -8841,7 +8746,9 @@
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TeamList": {
@ -8857,13 +8764,9 @@
},
"right": {
"description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.Right"
}
]
"maximum": 2
},
"team_id": {
"description": "The team id.",
@ -8872,7 +8775,9 @@
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TeamMember": {
@ -8893,7 +8798,9 @@
"username": {
"description": "The username of the member. We use this to prevent automated user id entering.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TeamNamespace": {
@ -8909,13 +8816,9 @@
},
"right": {
"description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0,
"maximum": 2,
"allOf": [
{
"$ref": "#/definitions/models.Right"
}
]
"maximum": 2
},
"team_id": {
"description": "The team id.",
@ -8924,7 +8827,9 @@
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.TeamUser": {
@ -8960,7 +8865,8 @@
"type": "string",
"maxLength": 250,
"minLength": 1
}
},
"web.Auth": {}
}
},
"models.TeamWithRight": {
@ -8972,11 +8878,7 @@
},
"created_by": {
"description": "The user who created this team.",
"allOf": [
{
"$ref": "#/definitions/user.User"
}
]
"$ref": "#/definitions/user.User"
},
"description": {
"description": "The team's description.",
@ -9000,12 +8902,16 @@
"minLength": 1
},
"right": {
"$ref": "#/definitions/models.Right"
"description": "The right this team has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0
},
"updated": {
"description": "A timestamp when this relation was last updated. You cannot change this value.",
"type": "string"
}
},
"web.CRUDable": {},
"web.Rights": {}
}
},
"models.UserWithRight": {
@ -9029,7 +8935,9 @@
"type": "string"
},
"right": {
"$ref": "#/definitions/models.Right"
"description": "The right this user has. 0 = Read only, 1 = Read \u0026 Write, 2 = Admin. See the docs for more details.",
"type": "integer",
"default": 0
},
"updated": {
"description": "A timestamp when this task was last updated. You cannot change this value.",
@ -9040,7 +8948,8 @@
"type": "string",
"maxLength": 250,
"minLength": 1
}
},
"web.Auth": {}
}
},
"notifications.DatabaseNotification": {
@ -9090,9 +8999,6 @@
"key": {
"type": "string"
},
"logout_url": {
"type": "string"
},
"name": {
"type": "string"
}
@ -9272,7 +9178,8 @@
"type": "string",
"maxLength": 250,
"minLength": 1
}
},
"web.Auth": {}
}
},
"v1.LinkShareAuth": {

View File

@ -58,9 +58,30 @@ definitions:
value.
type: string
created_by:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who initially created the bucket.
filter_by:
description: The field name of the field to filter by
items:
type: string
type: array
filter_comparator:
description: The comparator for field and value
items:
type: string
type: array
filter_concat:
description: The way all filter conditions are concatenated together, can
be either "and" or "or".,
type: string
filter_include_nulls:
description: If set to true, the result will also include null values
type: boolean
filter_value:
description: The value of the field name to filter by
items:
type: string
type: array
id:
description: The unique, numeric id of this bucket.
type: integer
@ -76,10 +97,22 @@ definitions:
list_id:
description: The list this bucket belongs to.
type: integer
order_by:
description: The query parameter to order the items by. This can be either
asc or desc, with asc being the default.
items:
type: string
type: array
position:
description: The position this bucket has when querying all buckets. See the
tasks.position property on how to use this.
type: number
sort_by:
description: The query parameter to sort by. This is for ex. done, priority,
etc.
items:
type: string
type: array
tasks:
description: All tasks which belong to this bucket.
items:
@ -93,6 +126,8 @@ definitions:
description: A timestamp when this bucket was last updated. You cannot change
this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.BulkAssignees:
properties:
@ -101,6 +136,8 @@ definitions:
items:
$ref: '#/definitions/user.User'
type: array
web.CRUDable: {}
web.Rights: {}
type: object
models.BulkTask:
properties:
@ -126,8 +163,7 @@ definitions:
value.
type: string
created_by:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who initially created the task.
description:
description: The task description.
@ -192,8 +228,7 @@ definitions:
sort by this later.
type: integer
related_tasks:
allOf:
- $ref: '#/definitions/models.RelatedTaskMap'
$ref: '#/definitions/models.RelatedTaskMap'
description: All related tasks, grouped by their relation kind
reminder_dates:
description: An array of datetimes when the user wants to be reminded of the
@ -207,18 +242,16 @@ definitions:
increase all remindes and the due date by its amount.
type: integer
repeat_mode:
allOf:
- $ref: '#/definitions/models.TaskRepeatMode'
description: 'Can have three possible values which will trigger when the task
is marked as done: 0 = repeats after the amount specified in repeat_after,
1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from
the current date rather than the last set date.'
type: integer
start_date:
description: When this task starts.
type: string
subscription:
allOf:
- $ref: '#/definitions/models.Subscription'
$ref: '#/definitions/models.Subscription'
description: |-
The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.
Will only returned when retreiving one task.
@ -235,6 +268,8 @@ definitions:
description: A timestamp when this task was last updated. You cannot change
this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.DatabaseNotifications:
properties:
@ -259,6 +294,8 @@ definitions:
description: When this notification is marked as read, this will be updated
with the current timestamp.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.Label:
properties:
@ -267,8 +304,7 @@ definitions:
value.
type: string
created_by:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who created this label
description:
description: The label description.
@ -290,6 +326,8 @@ definitions:
description: A timestamp when this label was last updated. You cannot change
this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.LabelTask:
properties:
@ -300,6 +338,8 @@ definitions:
label_id:
description: The label id you want to associate with a task.
type: integer
web.CRUDable: {}
web.Rights: {}
type: object
models.LabelTaskBulk:
properties:
@ -308,6 +348,8 @@ definitions:
items:
$ref: '#/definitions/models.Label'
type: array
web.CRUDable: {}
web.Rights: {}
type: object
models.LinkSharing:
properties:
@ -330,27 +372,26 @@ definitions:
it after the link share has been created.
type: string
right:
allOf:
- $ref: '#/definitions/models.Right'
default: 0
description: The right this list is shared with. 0 = Read only, 1 = Read &
Write, 2 = Admin. See the docs for more details.
maximum: 2
type: integer
shared_by:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who shared this list
sharing_type:
allOf:
- $ref: '#/definitions/models.SharingType'
default: 0
description: The kind of this link. 0 = undefined, 1 = without password, 2
= with password.
maximum: 2
type: integer
updated:
description: A timestamp when this share was last updated. You cannot change
this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.List:
properties:
@ -392,16 +433,14 @@ definitions:
namespace_id:
type: integer
owner:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who created this list.
position:
description: The position this list has when querying all lists. See the tasks.position
property on how to use this.
type: number
subscription:
allOf:
- $ref: '#/definitions/models.Subscription'
$ref: '#/definitions/models.Subscription'
description: |-
The subscription status for the user reading this list. You can only read this property, use the subscription endpoints to modify it.
Will only returned when retreiving one list.
@ -414,16 +453,19 @@ definitions:
description: A timestamp when this list was last updated. You cannot change
this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.ListDuplicate:
properties:
list:
allOf:
- $ref: '#/definitions/models.List'
$ref: '#/definitions/models.List'
description: The copied list
namespace_id:
description: The target namespace ID
type: integer
web.CRUDable: {}
web.Rights: {}
type: object
models.ListUser:
properties:
@ -435,12 +477,11 @@ definitions:
description: The unique, numeric id of this list <-> user relation.
type: integer
right:
allOf:
- $ref: '#/definitions/models.Right'
default: 0
description: The right this user has. 0 = Read only, 1 = Read & Write, 2 =
Admin. See the docs for more details.
maximum: 2
type: integer
updated:
description: A timestamp when this relation was last updated. You cannot change
this value.
@ -448,6 +489,8 @@ definitions:
user_id:
description: The username.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.Message:
properties:
@ -475,12 +518,10 @@ definitions:
description: Whether or not a namespace is archived.
type: boolean
owner:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who owns this namespace
subscription:
allOf:
- $ref: '#/definitions/models.Subscription'
$ref: '#/definitions/models.Subscription'
description: |-
The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.
Will only returned when retreiving one namespace.
@ -493,6 +534,8 @@ definitions:
description: A timestamp when this namespace was last updated. You cannot
change this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.NamespaceUser:
properties:
@ -504,12 +547,11 @@ definitions:
description: The unique, numeric id of this namespace <-> user relation.
type: integer
right:
allOf:
- $ref: '#/definitions/models.Right'
default: 0
description: The right this user has. 0 = Read only, 1 = Read & Write, 2 =
Admin. See the docs for more details.
maximum: 2
type: integer
updated:
description: A timestamp when this relation was last updated. You cannot change
this value.
@ -517,6 +559,8 @@ definitions:
user_id:
description: The username.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.NamespaceWithLists:
properties:
@ -542,12 +586,10 @@ definitions:
$ref: '#/definitions/models.List'
type: array
owner:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who owns this namespace
subscription:
allOf:
- $ref: '#/definitions/models.Subscription'
$ref: '#/definitions/models.Subscription'
description: |-
The subscription status for the user reading this namespace. You can only read this property, use the subscription endpoints to modify it.
Will only returned when retreiving one namespace.
@ -560,6 +602,8 @@ definitions:
description: A timestamp when this namespace was last updated. You cannot
change this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.RelatedTaskMap:
additionalProperties:
@ -567,44 +611,6 @@ definitions:
$ref: '#/definitions/models.Task'
type: array
type: object
models.RelationKind:
enum:
- unknown
- subtask
- parenttask
- related
- duplicateof
- duplicates
- blocking
- blocked
- precedes
- follows
- copiedfrom
- copiedto
type: string
x-enum-varnames:
- RelationKindUnknown
- RelationKindSubtask
- RelationKindParenttask
- RelationKindRelated
- RelationKindDuplicateOf
- RelationKindDuplicates
- RelationKindBlocking
- RelationKindBlocked
- RelationKindPreceeds
- RelationKindFollows
- RelationKindCopiedFrom
- RelationKindCopiedTo
models.Right:
enum:
- 0
- 1
- 2
type: integer
x-enum-varnames:
- RightRead
- RightWrite
- RightAdmin
models.SavedFilter:
properties:
created:
@ -615,8 +621,7 @@ definitions:
description: The description of the filter
type: string
filters:
allOf:
- $ref: '#/definitions/models.TaskCollection'
$ref: '#/definitions/models.TaskCollection'
description: The actual filters this filter contains
id:
description: The unique numeric id of this saved filter
@ -626,8 +631,7 @@ definitions:
a separate namespace together with favorite lists.
type: boolean
owner:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who owns this filter
title:
description: The title of the filter.
@ -638,17 +642,9 @@ definitions:
description: A timestamp when this filter was last updated. You cannot change
this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.SharingType:
enum:
- 0
- 1
- 2
type: integer
x-enum-varnames:
- SharingTypeUnknown
- SharingTypeWithoutPassword
- SharingTypeWithPassword
models.Subscription:
properties:
created:
@ -664,9 +660,10 @@ definitions:
description: The numeric ID of the subscription
type: integer
user:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who made this subscription
web.CRUDable: {}
web.Rights: {}
type: object
models.Task:
properties:
@ -692,8 +689,7 @@ definitions:
value.
type: string
created_by:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who initially created the task.
description:
description: The task description.
@ -758,8 +754,7 @@ definitions:
sort by this later.
type: integer
related_tasks:
allOf:
- $ref: '#/definitions/models.RelatedTaskMap'
$ref: '#/definitions/models.RelatedTaskMap'
description: All related tasks, grouped by their relation kind
reminder_dates:
description: An array of datetimes when the user wants to be reminded of the
@ -773,18 +768,16 @@ definitions:
increase all remindes and the due date by its amount.
type: integer
repeat_mode:
allOf:
- $ref: '#/definitions/models.TaskRepeatMode'
description: 'Can have three possible values which will trigger when the task
is marked as done: 0 = repeats after the amount specified in repeat_after,
1 = repeats all dates each months (ignoring repeat_after), 3 = repeats from
the current date rather than the last set date.'
type: integer
start_date:
description: When this task starts.
type: string
subscription:
allOf:
- $ref: '#/definitions/models.Subscription'
$ref: '#/definitions/models.Subscription'
description: |-
The subscription status for the user reading this task. You can only read this property, use the subscription endpoints to modify it.
Will only returned when retreiving one task.
@ -796,6 +789,8 @@ definitions:
description: A timestamp when this task was last updated. You cannot change
this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.TaskAssginee:
properties:
@ -803,6 +798,8 @@ definitions:
type: string
user_id:
type: integer
web.CRUDable: {}
web.Rights: {}
type: object
models.TaskAttachment:
properties:
@ -816,6 +813,8 @@ definitions:
type: integer
task_id:
type: integer
web.CRUDable: {}
web.Rights: {}
type: object
models.TaskCollection:
properties:
@ -853,6 +852,8 @@ definitions:
items:
type: string
type: array
web.CRUDable: {}
web.Rights: {}
type: object
models.TaskComment:
properties:
@ -866,6 +867,8 @@ definitions:
type: integer
updated:
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.TaskRelation:
properties:
@ -874,30 +877,20 @@ definitions:
value.
type: string
created_by:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who created this relation
other_task_id:
description: The ID of the other task, the task which is being related.
type: integer
relation_kind:
allOf:
- $ref: '#/definitions/models.RelationKind'
description: The kind of the relation.
type: string
task_id:
description: The ID of the "base" task, the task which has a relation to another.
type: integer
web.CRUDable: {}
web.Rights: {}
type: object
models.TaskRepeatMode:
enum:
- 0
- 1
- 2
type: integer
x-enum-varnames:
- TaskRepeatModeDefault
- TaskRepeatModeMonth
- TaskRepeatModeFromCurrentDate
models.Team:
properties:
created:
@ -905,8 +898,7 @@ definitions:
this value.
type: string
created_by:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who created this team.
description:
description: The team's description.
@ -928,6 +920,8 @@ definitions:
description: A timestamp when this relation was last updated. You cannot change
this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.TeamList:
properties:
@ -939,12 +933,11 @@ definitions:
description: The unique, numeric id of this list <-> team relation.
type: integer
right:
allOf:
- $ref: '#/definitions/models.Right'
default: 0
description: The right this team has. 0 = Read only, 1 = Read & Write, 2 =
Admin. See the docs for more details.
maximum: 2
type: integer
team_id:
description: The team id.
type: integer
@ -952,6 +945,8 @@ definitions:
description: A timestamp when this relation was last updated. You cannot change
this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.TeamMember:
properties:
@ -970,6 +965,8 @@ definitions:
description: The username of the member. We use this to prevent automated
user id entering.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.TeamNamespace:
properties:
@ -981,12 +978,11 @@ definitions:
description: The unique, numeric id of this namespace <-> team relation.
type: integer
right:
allOf:
- $ref: '#/definitions/models.Right'
default: 0
description: The right this team has. 0 = Read only, 1 = Read & Write, 2 =
Admin. See the docs for more details.
maximum: 2
type: integer
team_id:
description: The team id.
type: integer
@ -994,6 +990,8 @@ definitions:
description: A timestamp when this relation was last updated. You cannot change
this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.TeamUser:
properties:
@ -1024,6 +1022,7 @@ definitions:
maxLength: 250
minLength: 1
type: string
web.Auth: {}
type: object
models.TeamWithRight:
properties:
@ -1032,8 +1031,7 @@ definitions:
this value.
type: string
created_by:
allOf:
- $ref: '#/definitions/user.User'
$ref: '#/definitions/user.User'
description: The user who created this team.
description:
description: The team's description.
@ -1052,11 +1050,16 @@ definitions:
minLength: 1
type: string
right:
$ref: '#/definitions/models.Right'
default: 0
description: The right this team has. 0 = Read only, 1 = Read & Write, 2 =
Admin. See the docs for more details.
type: integer
updated:
description: A timestamp when this relation was last updated. You cannot change
this value.
type: string
web.CRUDable: {}
web.Rights: {}
type: object
models.UserWithRight:
properties:
@ -1075,7 +1078,10 @@ definitions:
description: The full name of the user.
type: string
right:
$ref: '#/definitions/models.Right'
default: 0
description: The right this user has. 0 = Read only, 1 = Read & Write, 2 =
Admin. See the docs for more details.
type: integer
updated:
description: A timestamp when this task was last updated. You cannot change
this value.
@ -1085,6 +1091,7 @@ definitions:
maxLength: 250
minLength: 1
type: string
web.Auth: {}
type: object
notifications.DatabaseNotification:
properties:
@ -1120,8 +1127,6 @@ definitions:
type: string
key:
type: string
logout_url:
type: string
name:
type: string
type: object
@ -1253,6 +1258,7 @@ definitions:
maxLength: 250
minLength: 1
type: string
web.Auth: {}
type: object
v1.LinkShareAuth:
properties: