Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
77f34e1149 | ||
![]() |
16136931a9 | ||
![]() |
c908ac94da | ||
![]() |
6604b6bbdd | ||
![]() |
2c227b5518 | ||
![]() |
e822b6f31a | ||
![]() |
a38e9d4e6c | ||
![]() |
deaf1e2ff7 | ||
![]() |
f324976801 | ||
![]() |
fad90ce1a8 | ||
![]() |
df406ba053 | ||
![]() |
4a7877a21b | ||
![]() |
79089cc009 | ||
![]() |
149d0cac7a | ||
![]() |
8863140e75 | ||
![]() |
b8ffadd36c |
3
.github/FUNDING.yml
vendored
Normal file
3
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# These are supported funding model platforms
|
||||||
|
|
||||||
|
github: authorizerdev
|
2
Makefile
2
Makefile
@@ -51,6 +51,6 @@ test-all-db:
|
|||||||
docker rm -vf authorizer_mongodb_db
|
docker rm -vf authorizer_mongodb_db
|
||||||
docker rm -vf authorizer_arangodb
|
docker rm -vf authorizer_arangodb
|
||||||
docker rm -vf dynamodb-local-test
|
docker rm -vf dynamodb-local-test
|
||||||
# docker rm -vf couchbase-local-test
|
docker rm -vf couchbase-local-test
|
||||||
generate:
|
generate:
|
||||||
cd server && go run github.com/99designs/gqlgen generate && go mod tidy
|
cd server && go run github.com/99designs/gqlgen generate && go mod tidy
|
||||||
|
@@ -12,7 +12,7 @@
|
|||||||
"author": "Lakhan Samani",
|
"author": "Lakhan Samani",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@authorizerdev/authorizer-react": "^1.1.8",
|
"@authorizerdev/authorizer-react": "^1.1.9",
|
||||||
"@types/react": "^17.0.15",
|
"@types/react": "^17.0.15",
|
||||||
"@types/react-dom": "^17.0.9",
|
"@types/react-dom": "^17.0.9",
|
||||||
"esbuild": "^0.12.17",
|
"esbuild": "^0.12.17",
|
||||||
|
626
app/pnpm-lock.yaml
generated
Normal file
626
app/pnpm-lock.yaml
generated
Normal file
@@ -0,0 +1,626 @@
|
|||||||
|
lockfileVersion: 5.4
|
||||||
|
|
||||||
|
specifiers:
|
||||||
|
'@authorizerdev/authorizer-react': ^1.1.9
|
||||||
|
'@types/react': ^17.0.15
|
||||||
|
'@types/react-dom': ^17.0.9
|
||||||
|
'@types/react-router-dom': ^5.1.8
|
||||||
|
'@types/styled-components': ^5.1.11
|
||||||
|
esbuild: ^0.12.17
|
||||||
|
prettier: 2.7.1
|
||||||
|
react: ^17.0.2
|
||||||
|
react-dom: ^17.0.2
|
||||||
|
react-is: ^17.0.2
|
||||||
|
react-router-dom: ^5.2.0
|
||||||
|
styled-components: ^5.3.0
|
||||||
|
typescript: ^4.3.5
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
'@authorizerdev/authorizer-react': 1.1.9_react@17.0.2
|
||||||
|
'@types/react': 17.0.53
|
||||||
|
'@types/react-dom': 17.0.19
|
||||||
|
esbuild: 0.12.29
|
||||||
|
react: 17.0.2
|
||||||
|
react-dom: 17.0.2_react@17.0.2
|
||||||
|
react-is: 17.0.2
|
||||||
|
react-router-dom: 5.3.4_react@17.0.2
|
||||||
|
styled-components: 5.3.9_fane7jikarojcev26y27hpbhu4
|
||||||
|
typescript: 4.9.5
|
||||||
|
|
||||||
|
devDependencies:
|
||||||
|
'@types/react-router-dom': 5.3.3
|
||||||
|
'@types/styled-components': 5.1.26
|
||||||
|
prettier: 2.7.1
|
||||||
|
|
||||||
|
packages:
|
||||||
|
|
||||||
|
/@authorizerdev/authorizer-js/1.2.1:
|
||||||
|
resolution: {integrity: sha512-/nFARvsHyZUsGFKrcYi8hgpnbThYR/NMJ2BJdQpWy/x7QsBnfLeCChBYWncbYHSIjFCa5PPKKfvhXM56HqVqsw==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
dependencies:
|
||||||
|
cross-fetch: 3.1.5
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- encoding
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@authorizerdev/authorizer-react/1.1.9_react@17.0.2:
|
||||||
|
resolution: {integrity: sha512-BlB4ixEm9nf+yjZ9OqIWbx5fMTmzeByEsNDAd5iYkt6HB+3Sk53DGiO5h6SgJznzPyqAwl8yg6y/QgbZreDTFA==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16'
|
||||||
|
dependencies:
|
||||||
|
'@authorizerdev/authorizer-js': 1.2.1
|
||||||
|
react: 17.0.2
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- encoding
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/code-frame/7.18.6:
|
||||||
|
resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/highlight': 7.18.6
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/generator/7.21.3:
|
||||||
|
resolution: {integrity: sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/types': 7.21.3
|
||||||
|
'@jridgewell/gen-mapping': 0.3.2
|
||||||
|
'@jridgewell/trace-mapping': 0.3.17
|
||||||
|
jsesc: 2.5.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/helper-annotate-as-pure/7.18.6:
|
||||||
|
resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/types': 7.21.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/helper-environment-visitor/7.18.9:
|
||||||
|
resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/helper-function-name/7.21.0:
|
||||||
|
resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/template': 7.20.7
|
||||||
|
'@babel/types': 7.21.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/helper-hoist-variables/7.18.6:
|
||||||
|
resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/types': 7.21.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/helper-module-imports/7.18.6:
|
||||||
|
resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/types': 7.21.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/helper-split-export-declaration/7.18.6:
|
||||||
|
resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/types': 7.21.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/helper-string-parser/7.19.4:
|
||||||
|
resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/helper-validator-identifier/7.19.1:
|
||||||
|
resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/highlight/7.18.6:
|
||||||
|
resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/helper-validator-identifier': 7.19.1
|
||||||
|
chalk: 2.4.2
|
||||||
|
js-tokens: 4.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/parser/7.21.3:
|
||||||
|
resolution: {integrity: sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/types': 7.21.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/runtime/7.21.0:
|
||||||
|
resolution: {integrity: sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
regenerator-runtime: 0.13.11
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/template/7.20.7:
|
||||||
|
resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/code-frame': 7.18.6
|
||||||
|
'@babel/parser': 7.21.3
|
||||||
|
'@babel/types': 7.21.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/traverse/7.21.3_supports-color@5.5.0:
|
||||||
|
resolution: {integrity: sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/code-frame': 7.18.6
|
||||||
|
'@babel/generator': 7.21.3
|
||||||
|
'@babel/helper-environment-visitor': 7.18.9
|
||||||
|
'@babel/helper-function-name': 7.21.0
|
||||||
|
'@babel/helper-hoist-variables': 7.18.6
|
||||||
|
'@babel/helper-split-export-declaration': 7.18.6
|
||||||
|
'@babel/parser': 7.21.3
|
||||||
|
'@babel/types': 7.21.3
|
||||||
|
debug: 4.3.4_supports-color@5.5.0
|
||||||
|
globals: 11.12.0
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- supports-color
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@babel/types/7.21.3:
|
||||||
|
resolution: {integrity: sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==}
|
||||||
|
engines: {node: '>=6.9.0'}
|
||||||
|
dependencies:
|
||||||
|
'@babel/helper-string-parser': 7.19.4
|
||||||
|
'@babel/helper-validator-identifier': 7.19.1
|
||||||
|
to-fast-properties: 2.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@emotion/is-prop-valid/1.2.0:
|
||||||
|
resolution: {integrity: sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==}
|
||||||
|
dependencies:
|
||||||
|
'@emotion/memoize': 0.8.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@emotion/memoize/0.8.0:
|
||||||
|
resolution: {integrity: sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@emotion/stylis/0.8.5:
|
||||||
|
resolution: {integrity: sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@emotion/unitless/0.7.5:
|
||||||
|
resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@jridgewell/gen-mapping/0.3.2:
|
||||||
|
resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/set-array': 1.1.2
|
||||||
|
'@jridgewell/sourcemap-codec': 1.4.14
|
||||||
|
'@jridgewell/trace-mapping': 0.3.17
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@jridgewell/resolve-uri/3.1.0:
|
||||||
|
resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@jridgewell/set-array/1.1.2:
|
||||||
|
resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@jridgewell/sourcemap-codec/1.4.14:
|
||||||
|
resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@jridgewell/trace-mapping/0.3.17:
|
||||||
|
resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==}
|
||||||
|
dependencies:
|
||||||
|
'@jridgewell/resolve-uri': 3.1.0
|
||||||
|
'@jridgewell/sourcemap-codec': 1.4.14
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/history/4.7.11:
|
||||||
|
resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@types/hoist-non-react-statics/3.3.1:
|
||||||
|
resolution: {integrity: sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==}
|
||||||
|
dependencies:
|
||||||
|
'@types/react': 17.0.53
|
||||||
|
hoist-non-react-statics: 3.3.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@types/prop-types/15.7.5:
|
||||||
|
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
|
||||||
|
|
||||||
|
/@types/react-dom/17.0.19:
|
||||||
|
resolution: {integrity: sha512-PiYG40pnQRdPHnlf7tZnp0aQ6q9tspYr72vD61saO6zFCybLfMqwUCN0va1/P+86DXn18ZWeW30Bk7xlC5eEAQ==}
|
||||||
|
dependencies:
|
||||||
|
'@types/react': 17.0.53
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/@types/react-router-dom/5.3.3:
|
||||||
|
resolution: {integrity: sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==}
|
||||||
|
dependencies:
|
||||||
|
'@types/history': 4.7.11
|
||||||
|
'@types/react': 17.0.53
|
||||||
|
'@types/react-router': 5.1.20
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@types/react-router/5.1.20:
|
||||||
|
resolution: {integrity: sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==}
|
||||||
|
dependencies:
|
||||||
|
'@types/history': 4.7.11
|
||||||
|
'@types/react': 17.0.53
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/@types/react/17.0.53:
|
||||||
|
resolution: {integrity: sha512-1yIpQR2zdYu1Z/dc1OxC+MA6GR240u3gcnP4l6mvj/PJiVaqHsQPmWttsvHsfnhfPbU2FuGmo0wSITPygjBmsw==}
|
||||||
|
dependencies:
|
||||||
|
'@types/prop-types': 15.7.5
|
||||||
|
'@types/scheduler': 0.16.3
|
||||||
|
csstype: 3.1.1
|
||||||
|
|
||||||
|
/@types/scheduler/0.16.3:
|
||||||
|
resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==}
|
||||||
|
|
||||||
|
/@types/styled-components/5.1.26:
|
||||||
|
resolution: {integrity: sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==}
|
||||||
|
dependencies:
|
||||||
|
'@types/hoist-non-react-statics': 3.3.1
|
||||||
|
'@types/react': 17.0.53
|
||||||
|
csstype: 3.1.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/ansi-styles/3.2.1:
|
||||||
|
resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dependencies:
|
||||||
|
color-convert: 1.9.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/babel-plugin-styled-components/2.0.7_styled-components@5.3.9:
|
||||||
|
resolution: {integrity: sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==}
|
||||||
|
peerDependencies:
|
||||||
|
styled-components: '>= 2'
|
||||||
|
dependencies:
|
||||||
|
'@babel/helper-annotate-as-pure': 7.18.6
|
||||||
|
'@babel/helper-module-imports': 7.18.6
|
||||||
|
babel-plugin-syntax-jsx: 6.18.0
|
||||||
|
lodash: 4.17.21
|
||||||
|
picomatch: 2.3.1
|
||||||
|
styled-components: 5.3.9_fane7jikarojcev26y27hpbhu4
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/babel-plugin-syntax-jsx/6.18.0:
|
||||||
|
resolution: {integrity: sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/camelize/1.0.1:
|
||||||
|
resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/chalk/2.4.2:
|
||||||
|
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dependencies:
|
||||||
|
ansi-styles: 3.2.1
|
||||||
|
escape-string-regexp: 1.0.5
|
||||||
|
supports-color: 5.5.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/color-convert/1.9.3:
|
||||||
|
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
||||||
|
dependencies:
|
||||||
|
color-name: 1.1.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/color-name/1.1.3:
|
||||||
|
resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/cross-fetch/3.1.5:
|
||||||
|
resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==}
|
||||||
|
dependencies:
|
||||||
|
node-fetch: 2.6.7
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- encoding
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/css-color-keywords/1.0.0:
|
||||||
|
resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/css-to-react-native/3.2.0:
|
||||||
|
resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==}
|
||||||
|
dependencies:
|
||||||
|
camelize: 1.0.1
|
||||||
|
css-color-keywords: 1.0.0
|
||||||
|
postcss-value-parser: 4.2.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/csstype/3.1.1:
|
||||||
|
resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==}
|
||||||
|
|
||||||
|
/debug/4.3.4_supports-color@5.5.0:
|
||||||
|
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||||
|
engines: {node: '>=6.0'}
|
||||||
|
peerDependencies:
|
||||||
|
supports-color: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
supports-color:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
ms: 2.1.2
|
||||||
|
supports-color: 5.5.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/esbuild/0.12.29:
|
||||||
|
resolution: {integrity: sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g==}
|
||||||
|
hasBin: true
|
||||||
|
requiresBuild: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/escape-string-regexp/1.0.5:
|
||||||
|
resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
|
||||||
|
engines: {node: '>=0.8.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/globals/11.12.0:
|
||||||
|
resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/has-flag/3.0.0:
|
||||||
|
resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/history/4.10.1:
|
||||||
|
resolution: {integrity: sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==}
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.21.0
|
||||||
|
loose-envify: 1.4.0
|
||||||
|
resolve-pathname: 3.0.0
|
||||||
|
tiny-invariant: 1.3.1
|
||||||
|
tiny-warning: 1.0.3
|
||||||
|
value-equal: 1.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/hoist-non-react-statics/3.3.2:
|
||||||
|
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
|
||||||
|
dependencies:
|
||||||
|
react-is: 16.13.1
|
||||||
|
|
||||||
|
/isarray/0.0.1:
|
||||||
|
resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/js-tokens/4.0.0:
|
||||||
|
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/jsesc/2.5.2:
|
||||||
|
resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/lodash/4.17.21:
|
||||||
|
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/loose-envify/1.4.0:
|
||||||
|
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
js-tokens: 4.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/ms/2.1.2:
|
||||||
|
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/node-fetch/2.6.7:
|
||||||
|
resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
|
||||||
|
engines: {node: 4.x || >=6.0.0}
|
||||||
|
peerDependencies:
|
||||||
|
encoding: ^0.1.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
encoding:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
whatwg-url: 5.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/object-assign/4.1.1:
|
||||||
|
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/path-to-regexp/1.8.0:
|
||||||
|
resolution: {integrity: sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==}
|
||||||
|
dependencies:
|
||||||
|
isarray: 0.0.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/picomatch/2.3.1:
|
||||||
|
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||||
|
engines: {node: '>=8.6'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/postcss-value-parser/4.2.0:
|
||||||
|
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/prettier/2.7.1:
|
||||||
|
resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==}
|
||||||
|
engines: {node: '>=10.13.0'}
|
||||||
|
hasBin: true
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/prop-types/15.8.1:
|
||||||
|
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
||||||
|
dependencies:
|
||||||
|
loose-envify: 1.4.0
|
||||||
|
object-assign: 4.1.1
|
||||||
|
react-is: 16.13.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/react-dom/17.0.2_react@17.0.2:
|
||||||
|
resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==}
|
||||||
|
peerDependencies:
|
||||||
|
react: 17.0.2
|
||||||
|
dependencies:
|
||||||
|
loose-envify: 1.4.0
|
||||||
|
object-assign: 4.1.1
|
||||||
|
react: 17.0.2
|
||||||
|
scheduler: 0.20.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/react-is/16.13.1:
|
||||||
|
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||||
|
|
||||||
|
/react-is/17.0.2:
|
||||||
|
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/react-router-dom/5.3.4_react@17.0.2:
|
||||||
|
resolution: {integrity: sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=15'
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.21.0
|
||||||
|
history: 4.10.1
|
||||||
|
loose-envify: 1.4.0
|
||||||
|
prop-types: 15.8.1
|
||||||
|
react: 17.0.2
|
||||||
|
react-router: 5.3.4_react@17.0.2
|
||||||
|
tiny-invariant: 1.3.1
|
||||||
|
tiny-warning: 1.0.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/react-router/5.3.4_react@17.0.2:
|
||||||
|
resolution: {integrity: sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=15'
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.21.0
|
||||||
|
history: 4.10.1
|
||||||
|
hoist-non-react-statics: 3.3.2
|
||||||
|
loose-envify: 1.4.0
|
||||||
|
path-to-regexp: 1.8.0
|
||||||
|
prop-types: 15.8.1
|
||||||
|
react: 17.0.2
|
||||||
|
react-is: 16.13.1
|
||||||
|
tiny-invariant: 1.3.1
|
||||||
|
tiny-warning: 1.0.3
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/react/17.0.2:
|
||||||
|
resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
dependencies:
|
||||||
|
loose-envify: 1.4.0
|
||||||
|
object-assign: 4.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/regenerator-runtime/0.13.11:
|
||||||
|
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/resolve-pathname/3.0.0:
|
||||||
|
resolution: {integrity: sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/scheduler/0.20.2:
|
||||||
|
resolution: {integrity: sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==}
|
||||||
|
dependencies:
|
||||||
|
loose-envify: 1.4.0
|
||||||
|
object-assign: 4.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/shallowequal/1.1.0:
|
||||||
|
resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/styled-components/5.3.9_fane7jikarojcev26y27hpbhu4:
|
||||||
|
resolution: {integrity: sha512-Aj3kb13B75DQBo2oRwRa/APdB5rSmwUfN5exyarpX+x/tlM/rwZA2vVk2vQgVSP6WKaZJHWwiFrzgHt+CLtB4A==}
|
||||||
|
engines: {node: '>=10'}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>= 16.8.0'
|
||||||
|
react-dom: '>= 16.8.0'
|
||||||
|
react-is: '>= 16.8.0'
|
||||||
|
dependencies:
|
||||||
|
'@babel/helper-module-imports': 7.18.6
|
||||||
|
'@babel/traverse': 7.21.3_supports-color@5.5.0
|
||||||
|
'@emotion/is-prop-valid': 1.2.0
|
||||||
|
'@emotion/stylis': 0.8.5
|
||||||
|
'@emotion/unitless': 0.7.5
|
||||||
|
babel-plugin-styled-components: 2.0.7_styled-components@5.3.9
|
||||||
|
css-to-react-native: 3.2.0
|
||||||
|
hoist-non-react-statics: 3.3.2
|
||||||
|
react: 17.0.2
|
||||||
|
react-dom: 17.0.2_react@17.0.2
|
||||||
|
react-is: 17.0.2
|
||||||
|
shallowequal: 1.1.0
|
||||||
|
supports-color: 5.5.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/supports-color/5.5.0:
|
||||||
|
resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dependencies:
|
||||||
|
has-flag: 3.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/tiny-invariant/1.3.1:
|
||||||
|
resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/tiny-warning/1.0.3:
|
||||||
|
resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/to-fast-properties/2.0.0:
|
||||||
|
resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
|
||||||
|
engines: {node: '>=4'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/tr46/0.0.3:
|
||||||
|
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/typescript/4.9.5:
|
||||||
|
resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==}
|
||||||
|
engines: {node: '>=4.2.0'}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/value-equal/1.0.1:
|
||||||
|
resolution: {integrity: sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/webidl-conversions/3.0.1:
|
||||||
|
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/whatwg-url/5.0.0:
|
||||||
|
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||||
|
dependencies:
|
||||||
|
tr46: 0.0.3
|
||||||
|
webidl-conversions: 3.0.1
|
||||||
|
dev: false
|
@@ -63,6 +63,7 @@ interface headersValidatorDataType {
|
|||||||
interface selecetdWebhookDataTypes {
|
interface selecetdWebhookDataTypes {
|
||||||
[WebhookInputDataFields.ID]: string;
|
[WebhookInputDataFields.ID]: string;
|
||||||
[WebhookInputDataFields.EVENT_NAME]: string;
|
[WebhookInputDataFields.EVENT_NAME]: string;
|
||||||
|
[WebhookInputDataFields.EVENT_DESCRIPTION]?: string;
|
||||||
[WebhookInputDataFields.ENDPOINT]: string;
|
[WebhookInputDataFields.ENDPOINT]: string;
|
||||||
[WebhookInputDataFields.ENABLED]: boolean;
|
[WebhookInputDataFields.ENABLED]: boolean;
|
||||||
[WebhookInputDataFields.HEADERS]?: Record<string, string>;
|
[WebhookInputDataFields.HEADERS]?: Record<string, string>;
|
||||||
@@ -86,6 +87,7 @@ const initHeadersValidatorData: headersValidatorDataType = {
|
|||||||
|
|
||||||
interface webhookDataType {
|
interface webhookDataType {
|
||||||
[WebhookInputDataFields.EVENT_NAME]: string;
|
[WebhookInputDataFields.EVENT_NAME]: string;
|
||||||
|
[WebhookInputDataFields.EVENT_DESCRIPTION]?: string;
|
||||||
[WebhookInputDataFields.ENDPOINT]: string;
|
[WebhookInputDataFields.ENDPOINT]: string;
|
||||||
[WebhookInputDataFields.ENABLED]: boolean;
|
[WebhookInputDataFields.ENABLED]: boolean;
|
||||||
[WebhookInputDataFields.HEADERS]: headersDataType[];
|
[WebhookInputDataFields.HEADERS]: headersDataType[];
|
||||||
@@ -98,6 +100,7 @@ interface validatorDataType {
|
|||||||
|
|
||||||
const initWebhookData: webhookDataType = {
|
const initWebhookData: webhookDataType = {
|
||||||
[WebhookInputDataFields.EVENT_NAME]: webhookEventNames['User login'],
|
[WebhookInputDataFields.EVENT_NAME]: webhookEventNames['User login'],
|
||||||
|
[WebhookInputDataFields.EVENT_DESCRIPTION]: '',
|
||||||
[WebhookInputDataFields.ENDPOINT]: '',
|
[WebhookInputDataFields.ENDPOINT]: '',
|
||||||
[WebhookInputDataFields.ENABLED]: true,
|
[WebhookInputDataFields.ENABLED]: true,
|
||||||
[WebhookInputDataFields.HEADERS]: [{ ...initHeadersData }],
|
[WebhookInputDataFields.HEADERS]: [{ ...initHeadersData }],
|
||||||
@@ -144,6 +147,9 @@ const UpdateWebhookModal = ({
|
|||||||
case WebhookInputDataFields.EVENT_NAME:
|
case WebhookInputDataFields.EVENT_NAME:
|
||||||
setWebhook({ ...webhook, [inputType]: value });
|
setWebhook({ ...webhook, [inputType]: value });
|
||||||
break;
|
break;
|
||||||
|
case WebhookInputDataFields.EVENT_DESCRIPTION:
|
||||||
|
setWebhook({ ...webhook, [inputType]: value });
|
||||||
|
break;
|
||||||
case WebhookInputDataFields.ENDPOINT:
|
case WebhookInputDataFields.ENDPOINT:
|
||||||
setWebhook({ ...webhook, [inputType]: value });
|
setWebhook({ ...webhook, [inputType]: value });
|
||||||
setValidator({
|
setValidator({
|
||||||
@@ -246,6 +252,8 @@ const UpdateWebhookModal = ({
|
|||||||
let params: any = {
|
let params: any = {
|
||||||
[WebhookInputDataFields.EVENT_NAME]:
|
[WebhookInputDataFields.EVENT_NAME]:
|
||||||
webhook[WebhookInputDataFields.EVENT_NAME],
|
webhook[WebhookInputDataFields.EVENT_NAME],
|
||||||
|
[WebhookInputDataFields.EVENT_DESCRIPTION]:
|
||||||
|
webhook[WebhookInputDataFields.EVENT_DESCRIPTION],
|
||||||
[WebhookInputDataFields.ENDPOINT]:
|
[WebhookInputDataFields.ENDPOINT]:
|
||||||
webhook[WebhookInputDataFields.ENDPOINT],
|
webhook[WebhookInputDataFields.ENDPOINT],
|
||||||
[WebhookInputDataFields.ENABLED]: webhook[WebhookInputDataFields.ENABLED],
|
[WebhookInputDataFields.ENABLED]: webhook[WebhookInputDataFields.ENABLED],
|
||||||
@@ -402,7 +410,9 @@ const UpdateWebhookModal = ({
|
|||||||
<Flex flex="3">
|
<Flex flex="3">
|
||||||
<Select
|
<Select
|
||||||
size="md"
|
size="md"
|
||||||
value={webhook[WebhookInputDataFields.EVENT_NAME]}
|
value={
|
||||||
|
webhook[WebhookInputDataFields.EVENT_NAME].split('-')[0]
|
||||||
|
}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
inputChangehandler(
|
inputChangehandler(
|
||||||
WebhookInputDataFields.EVENT_NAME,
|
WebhookInputDataFields.EVENT_NAME,
|
||||||
@@ -420,6 +430,30 @@ const UpdateWebhookModal = ({
|
|||||||
</Select>
|
</Select>
|
||||||
</Flex>
|
</Flex>
|
||||||
</Flex>
|
</Flex>
|
||||||
|
<Flex
|
||||||
|
width="100%"
|
||||||
|
justifyContent="start"
|
||||||
|
alignItems="center"
|
||||||
|
marginBottom="5%"
|
||||||
|
>
|
||||||
|
<Flex flex="1">Event Description</Flex>
|
||||||
|
<Flex flex="3">
|
||||||
|
<InputGroup size="md">
|
||||||
|
<Input
|
||||||
|
pr="4.5rem"
|
||||||
|
type="text"
|
||||||
|
placeholder="User event"
|
||||||
|
value={webhook[WebhookInputDataFields.EVENT_DESCRIPTION]}
|
||||||
|
onChange={(e) =>
|
||||||
|
inputChangehandler(
|
||||||
|
WebhookInputDataFields.EVENT_DESCRIPTION,
|
||||||
|
e.currentTarget.value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</InputGroup>
|
||||||
|
</Flex>
|
||||||
|
</Flex>
|
||||||
<Flex
|
<Flex
|
||||||
width="100%"
|
width="100%"
|
||||||
justifyContent="start"
|
justifyContent="start"
|
||||||
|
@@ -179,6 +179,7 @@ export const envSubViews = {
|
|||||||
|
|
||||||
export enum WebhookInputDataFields {
|
export enum WebhookInputDataFields {
|
||||||
ID = 'id',
|
ID = 'id',
|
||||||
|
EVENT_DESCRIPTION = 'event_description',
|
||||||
EVENT_NAME = 'event_name',
|
EVENT_NAME = 'event_name',
|
||||||
ENDPOINT = 'endpoint',
|
ENDPOINT = 'endpoint',
|
||||||
ENABLED = 'enabled',
|
ENABLED = 'enabled',
|
||||||
|
@@ -118,6 +118,7 @@ export const WebhooksDataQuery = `
|
|||||||
_webhooks(params: $params){
|
_webhooks(params: $params){
|
||||||
webhooks{
|
webhooks{
|
||||||
id
|
id
|
||||||
|
event_description
|
||||||
event_name
|
event_name
|
||||||
endpoint
|
endpoint
|
||||||
enabled
|
enabled
|
||||||
|
@@ -56,6 +56,7 @@ interface paginationPropTypes {
|
|||||||
interface webhookDataTypes {
|
interface webhookDataTypes {
|
||||||
[WebhookInputDataFields.ID]: string;
|
[WebhookInputDataFields.ID]: string;
|
||||||
[WebhookInputDataFields.EVENT_NAME]: string;
|
[WebhookInputDataFields.EVENT_NAME]: string;
|
||||||
|
[WebhookInputDataFields.EVENT_DESCRIPTION]?: string;
|
||||||
[WebhookInputDataFields.ENDPOINT]: string;
|
[WebhookInputDataFields.ENDPOINT]: string;
|
||||||
[WebhookInputDataFields.ENABLED]: boolean;
|
[WebhookInputDataFields.ENABLED]: boolean;
|
||||||
[WebhookInputDataFields.HEADERS]?: Record<string, string>;
|
[WebhookInputDataFields.HEADERS]?: Record<string, string>;
|
||||||
@@ -117,6 +118,7 @@ const Webhooks = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchWebookData();
|
fetchWebookData();
|
||||||
}, [paginationProps.page, paginationProps.limit]);
|
}, [paginationProps.page, paginationProps.limit]);
|
||||||
|
console.log({ webhookData });
|
||||||
return (
|
return (
|
||||||
<Box m="5" py="5" px="10" bg="white" rounded="md">
|
<Box m="5" py="5" px="10" bg="white" rounded="md">
|
||||||
<Flex margin="2% 0" justifyContent="space-between" alignItems="center">
|
<Flex margin="2% 0" justifyContent="space-between" alignItems="center">
|
||||||
@@ -134,6 +136,7 @@ const Webhooks = () => {
|
|||||||
<Thead>
|
<Thead>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th>Event Name</Th>
|
<Th>Event Name</Th>
|
||||||
|
<Th>Event Description</Th>
|
||||||
<Th>Endpoint</Th>
|
<Th>Endpoint</Th>
|
||||||
<Th>Enabled</Th>
|
<Th>Enabled</Th>
|
||||||
<Th>Headers</Th>
|
<Th>Headers</Th>
|
||||||
@@ -147,7 +150,10 @@ const Webhooks = () => {
|
|||||||
style={{ fontSize: 14 }}
|
style={{ fontSize: 14 }}
|
||||||
>
|
>
|
||||||
<Td maxW="300">
|
<Td maxW="300">
|
||||||
{webhook[WebhookInputDataFields.EVENT_NAME]}
|
{webhook[WebhookInputDataFields.EVENT_NAME].split('-')[0]}
|
||||||
|
</Td>
|
||||||
|
<Td maxW="300">
|
||||||
|
{webhook[WebhookInputDataFields.EVENT_DESCRIPTION]}
|
||||||
</Td>
|
</Td>
|
||||||
<Td>{webhook[WebhookInputDataFields.ENDPOINT]}</Td>
|
<Td>{webhook[WebhookInputDataFields.ENDPOINT]}</Td>
|
||||||
<Td>
|
<Td>
|
||||||
@@ -264,7 +270,7 @@ const Webhooks = () => {
|
|||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
<Flex alignItems="center">
|
<Flex alignItems="center">
|
||||||
<Text flexShrink="0">Go to page:</Text>{' '}
|
<Text>Go to page:</Text>{' '}
|
||||||
<NumberInput
|
<NumberInput
|
||||||
ml={2}
|
ml={2}
|
||||||
mr={8}
|
mr={8}
|
||||||
|
@@ -10,11 +10,15 @@ import (
|
|||||||
|
|
||||||
// Note: any change here should be reflected in providers/casandra/provider.go as it does not have model support in collection creation
|
// Note: any change here should be reflected in providers/casandra/provider.go as it does not have model support in collection creation
|
||||||
|
|
||||||
|
// Event name has been kept unique as per initial design. But later on decided that we can have
|
||||||
|
// multiple hooks for same event so will be in a pattern `event_name-TIMESTAMP`
|
||||||
|
|
||||||
// Webhook model for db
|
// Webhook model for db
|
||||||
type Webhook struct {
|
type Webhook struct {
|
||||||
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
|
||||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
|
||||||
EventName string `gorm:"unique" json:"event_name" bson:"event_name" cql:"event_name" dynamo:"event_name" index:"event_name,hash"`
|
EventName string `gorm:"unique" json:"event_name" bson:"event_name" cql:"event_name" dynamo:"event_name" index:"event_name,hash"`
|
||||||
|
EventDescription string `json:"event_description" bson:"event_description" cql:"event_description" dynamo:"event_description"`
|
||||||
EndPoint string `json:"endpoint" bson:"endpoint" cql:"endpoint" dynamo:"endpoint"`
|
EndPoint string `json:"endpoint" bson:"endpoint" cql:"endpoint" dynamo:"endpoint"`
|
||||||
Headers string `json:"headers" bson:"headers" cql:"headers" dynamo:"headers"`
|
Headers string `json:"headers" bson:"headers" cql:"headers" dynamo:"headers"`
|
||||||
Enabled bool `json:"enabled" bson:"enabled" cql:"enabled" dynamo:"enabled"`
|
Enabled bool `json:"enabled" bson:"enabled" cql:"enabled" dynamo:"enabled"`
|
||||||
@@ -26,15 +30,18 @@ type Webhook struct {
|
|||||||
func (w *Webhook) AsAPIWebhook() *model.Webhook {
|
func (w *Webhook) AsAPIWebhook() *model.Webhook {
|
||||||
headersMap := make(map[string]interface{})
|
headersMap := make(map[string]interface{})
|
||||||
json.Unmarshal([]byte(w.Headers), &headersMap)
|
json.Unmarshal([]byte(w.Headers), &headersMap)
|
||||||
|
|
||||||
id := w.ID
|
id := w.ID
|
||||||
if strings.Contains(id, Collections.Webhook+"/") {
|
if strings.Contains(id, Collections.Webhook+"/") {
|
||||||
id = strings.TrimPrefix(id, Collections.Webhook+"/")
|
id = strings.TrimPrefix(id, Collections.Webhook+"/")
|
||||||
}
|
}
|
||||||
|
// set default title to event name without dot(.)
|
||||||
|
if w.EventDescription == "" {
|
||||||
|
w.EventDescription = strings.Join(strings.Split(w.EventName, "."), " ")
|
||||||
|
}
|
||||||
return &model.Webhook{
|
return &model.Webhook{
|
||||||
ID: id,
|
ID: id,
|
||||||
EventName: refs.NewStringRef(w.EventName),
|
EventName: refs.NewStringRef(w.EventName),
|
||||||
|
EventDescription: refs.NewStringRef(w.EventDescription),
|
||||||
Endpoint: refs.NewStringRef(w.EndPoint),
|
Endpoint: refs.NewStringRef(w.EndPoint),
|
||||||
Headers: headersMap,
|
Headers: headersMap,
|
||||||
Enabled: refs.NewBoolRef(w.Enabled),
|
Enabled: refs.NewBoolRef(w.Enabled),
|
||||||
|
@@ -3,8 +3,10 @@ package arangodb
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/arangodb/go-driver"
|
||||||
arangoDriver "github.com/arangodb/go-driver"
|
arangoDriver "github.com/arangodb/go-driver"
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
@@ -17,8 +19,9 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
|||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
webhookCollection, _ := p.db.Collection(ctx, models.Collections.Webhook)
|
webhookCollection, _ := p.db.Collection(ctx, models.Collections.Webhook)
|
||||||
@@ -32,12 +35,15 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
|||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
webhookCollection, _ := p.db.Collection(ctx, models.Collections.Webhook)
|
webhookCollection, _ := p.db.Collection(ctx, models.Collections.Webhook)
|
||||||
meta, err := webhookCollection.UpdateDocument(ctx, webhook.Key, webhook)
|
meta, err := webhookCollection.UpdateDocument(ctx, webhook.Key, webhook)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = meta.Key
|
webhook.Key = meta.Key
|
||||||
webhook.ID = meta.ID.String()
|
webhook.ID = meta.ID.String()
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
@@ -55,10 +61,8 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cursor.Close()
|
defer cursor.Close()
|
||||||
|
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
paginationClone.Total = cursor.Statistics().FullCount()
|
paginationClone.Total = cursor.Statistics().FullCount()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
meta, err := cursor.ReadDocument(ctx, &webhook)
|
meta, err := cursor.ReadDocument(ctx, &webhook)
|
||||||
@@ -87,13 +91,11 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
|||||||
bindVars := map[string]interface{}{
|
bindVars := map[string]interface{}{
|
||||||
"webhook_id": webhookID,
|
"webhook_id": webhookID,
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor, err := p.db.Query(ctx, query, bindVars)
|
cursor, err := p.db.Query(ctx, query, bindVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cursor.Close()
|
defer cursor.Close()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if !cursor.HasMore() {
|
if !cursor.HasMore() {
|
||||||
if webhook.Key == "" {
|
if webhook.Key == "" {
|
||||||
@@ -110,32 +112,28 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
query := fmt.Sprintf("FOR d in %s FILTER d.event_name LIKE @event_name RETURN d", models.Collections.Webhook)
|
||||||
query := fmt.Sprintf("FOR d in %s FILTER d.event_name == @event_name RETURN d", models.Collections.Webhook)
|
|
||||||
bindVars := map[string]interface{}{
|
bindVars := map[string]interface{}{
|
||||||
"event_name": eventName,
|
"event_name": eventName + "%",
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor, err := p.db.Query(ctx, query, bindVars)
|
cursor, err := p.db.Query(ctx, query, bindVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cursor.Close()
|
defer cursor.Close()
|
||||||
|
webhooks := []*model.Webhook{}
|
||||||
for {
|
for {
|
||||||
if !cursor.HasMore() {
|
var webhook models.Webhook
|
||||||
if webhook.Key == "" {
|
if _, err := cursor.ReadDocument(ctx, &webhook); driver.IsNoMoreDocuments(err) {
|
||||||
return nil, fmt.Errorf("webhook not found")
|
// We're done
|
||||||
}
|
|
||||||
break
|
break
|
||||||
}
|
} else if err != nil {
|
||||||
_, err := cursor.ReadDocument(ctx, &webhook)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
||||||
}
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhooks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
@@ -145,17 +143,14 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
query := fmt.Sprintf("FOR d IN %s FILTER d.webhook_id == @webhook_id REMOVE { _key: d._key } IN %s", models.Collections.WebhookLog, models.Collections.WebhookLog)
|
query := fmt.Sprintf("FOR d IN %s FILTER d.webhook_id == @webhook_id REMOVE { _key: d._key } IN %s", models.Collections.WebhookLog, models.Collections.WebhookLog)
|
||||||
bindVars := map[string]interface{}{
|
bindVars := map[string]interface{}{
|
||||||
"webhook_id": webhook.ID,
|
"webhook_id": webhook.ID,
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor, err := p.db.Query(ctx, query, bindVars)
|
cursor, err := p.db.Query(ctx, query, bindVars)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cursor.Close()
|
defer cursor.Close()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -207,6 +207,13 @@ func NewProvider() (*provider, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
// add event_description to webhook table
|
||||||
|
webhookAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (event_description text);`, KeySpace, models.Collections.Webhook)
|
||||||
|
err = session.Query(webhookAlterQuery).Exec()
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to alter table as column exists: ", err)
|
||||||
|
// continue
|
||||||
|
}
|
||||||
|
|
||||||
webhookLogCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, http_status bigint, response text, request text, webhook_id text,updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.WebhookLog)
|
webhookLogCollectionQuery := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s.%s (id text, http_status bigint, response text, request text, webhook_id text,updated_at bigint, created_at bigint, PRIMARY KEY (id))", KeySpace, models.Collections.WebhookLog)
|
||||||
err = session.Query(webhookLogCollectionQuery).Exec()
|
err = session.Query(webhookLogCollectionQuery).Exec()
|
||||||
|
@@ -19,29 +19,26 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
|||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
existingHook, _ := p.GetWebhookByEventName(ctx, webhook.EventName)
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
if existingHook != nil {
|
insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', '%s', %t, %d, %d)", KeySpace+"."+models.Collections.Webhook, webhook.ID, webhook.EventDescription, webhook.EventName, webhook.EndPoint, webhook.Headers, webhook.Enabled, webhook.CreatedAt, webhook.UpdatedAt)
|
||||||
return nil, fmt.Errorf("Webhook with %s event_name already exists", webhook.EventName)
|
|
||||||
}
|
|
||||||
|
|
||||||
insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_name, endpoint, headers, enabled, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', %t, %d, %d)", KeySpace+"."+models.Collections.Webhook, webhook.ID, webhook.EventName, webhook.EndPoint, webhook.Headers, webhook.Enabled, webhook.CreatedAt, webhook.UpdatedAt)
|
|
||||||
err := p.db.Query(insertQuery).Exec()
|
err := p.db.Query(insertQuery).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
bytes, err := json.Marshal(webhook)
|
bytes, err := json.Marshal(webhook)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -54,22 +51,18 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFields := ""
|
updateFields := ""
|
||||||
for key, value := range webhookMap {
|
for key, value := range webhookMap {
|
||||||
if key == "_id" {
|
if key == "_id" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if key == "_key" {
|
if key == "_key" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if value == nil {
|
if value == nil {
|
||||||
updateFields += fmt.Sprintf("%s = null,", key)
|
updateFields += fmt.Sprintf("%s = null,", key)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
valueType := reflect.TypeOf(value)
|
valueType := reflect.TypeOf(value)
|
||||||
if valueType.Name() == "string" {
|
if valueType.Name() == "string" {
|
||||||
updateFields += fmt.Sprintf("%s = '%s', ", key, value.(string))
|
updateFields += fmt.Sprintf("%s = '%s', ", key, value.(string))
|
||||||
@@ -79,7 +72,6 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
|
|||||||
}
|
}
|
||||||
updateFields = strings.Trim(updateFields, " ")
|
updateFields = strings.Trim(updateFields, " ")
|
||||||
updateFields = strings.TrimSuffix(updateFields, ",")
|
updateFields = strings.TrimSuffix(updateFields, ",")
|
||||||
|
|
||||||
query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+models.Collections.Webhook, updateFields, webhook.ID)
|
query := fmt.Sprintf("UPDATE %s SET %s WHERE id = '%s'", KeySpace+"."+models.Collections.Webhook, updateFields, webhook.ID)
|
||||||
err = p.db.Query(query).Exec()
|
err = p.db.Query(query).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -92,24 +84,21 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
|
|||||||
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
||||||
webhooks := []*model.Webhook{}
|
webhooks := []*model.Webhook{}
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
|
|
||||||
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.Webhook)
|
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.Webhook)
|
||||||
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
|
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// there is no offset in cassandra
|
// there is no offset in cassandra
|
||||||
// so we fetch till limit + offset
|
// so we fetch till limit + offset
|
||||||
// and return the results from offset to limit
|
// and return the results from offset to limit
|
||||||
query := fmt.Sprintf("SELECT id, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.Webhook, pagination.Limit+pagination.Offset)
|
query := fmt.Sprintf("SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.Webhook, pagination.Limit+pagination.Offset)
|
||||||
|
|
||||||
scanner := p.db.Query(query).Iter().Scanner()
|
scanner := p.db.Query(query).Iter().Scanner()
|
||||||
counter := int64(0)
|
counter := int64(0)
|
||||||
for scanner.Next() {
|
for scanner.Next() {
|
||||||
if counter >= pagination.Offset {
|
if counter >= pagination.Offset {
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
err := scanner.Scan(&webhook.ID, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
err := scanner.Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -127,8 +116,8 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
|||||||
// GetWebhookByID to get webhook by id
|
// GetWebhookByID to get webhook by id
|
||||||
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
query := fmt.Sprintf(`SELECT id, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.Webhook, webhookID)
|
query := fmt.Sprintf(`SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1`, KeySpace+"."+models.Collections.Webhook, webhookID)
|
||||||
err := p.db.Query(query).Consistency(gocql.One).Scan(&webhook.ID, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
err := p.db.Query(query).Consistency(gocql.One).Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -136,14 +125,19 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
|
query := fmt.Sprintf(`SELECT id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE event_name LIKE '%s' ALLOW FILTERING`, KeySpace+"."+models.Collections.Webhook, eventName+"%")
|
||||||
|
scanner := p.db.Query(query).Iter().Scanner()
|
||||||
|
webhooks := []*model.Webhook{}
|
||||||
|
for scanner.Next() {
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
query := fmt.Sprintf(`SELECT id, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s WHERE event_name = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.Webhook, eventName)
|
err := scanner.Scan(&webhook.ID, &webhook.EventDescription, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
||||||
err := p.db.Query(query).Consistency(gocql.One).Scan(&webhook.ID, &webhook.EventName, &webhook.EndPoint, &webhook.Headers, &webhook.Enabled, &webhook.CreatedAt, &webhook.UpdatedAt)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
||||||
|
}
|
||||||
|
return webhooks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
|
@@ -19,11 +19,11 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
|||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
insertOpt := gocb.InsertOptions{
|
insertOpt := gocb.InsertOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,10 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
|||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
bytes, err := json.Marshal(webhook)
|
bytes, err := json.Marshal(webhook)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -50,17 +53,13 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFields, params := GetSetFields(webhookMap)
|
updateFields, params := GetSetFields(webhookMap)
|
||||||
|
|
||||||
query := fmt.Sprintf(`UPDATE %s.%s SET %s WHERE _id='%s'`, p.scopeName, models.Collections.Webhook, updateFields, webhook.ID)
|
query := fmt.Sprintf(`UPDATE %s.%s SET %s WHERE _id='%s'`, p.scopeName, models.Collections.Webhook, updateFields, webhook.ID)
|
||||||
|
|
||||||
_, err = p.db.Query(query, &gocb.QueryOptions{
|
_, err = p.db.Query(query, &gocb.QueryOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
||||||
NamedParameters: params,
|
NamedParameters: params,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -72,7 +71,6 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
|
|||||||
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
||||||
webhooks := []*model.Webhook{}
|
webhooks := []*model.Webhook{}
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
|
|
||||||
params := make(map[string]interface{}, 1)
|
params := make(map[string]interface{}, 1)
|
||||||
params["offset"] = paginationClone.Offset
|
params["offset"] = paginationClone.Offset
|
||||||
params["limit"] = paginationClone.Limit
|
params["limit"] = paginationClone.Limit
|
||||||
@@ -81,7 +79,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
paginationClone.Total = total
|
paginationClone.Total = total
|
||||||
query := fmt.Sprintf("SELECT _id, env, created_at, updated_at FROM %s.%s OFFSET $offset LIMIT $limit", p.scopeName, models.Collections.Webhook)
|
query := fmt.Sprintf("SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s OFFSET $offset LIMIT $limit", p.scopeName, models.Collections.Webhook)
|
||||||
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
|
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
||||||
@@ -110,11 +108,9 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
|||||||
// GetWebhookByID to get webhook by id
|
// GetWebhookByID to get webhook by id
|
||||||
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
|
|
||||||
params := make(map[string]interface{}, 1)
|
params := make(map[string]interface{}, 1)
|
||||||
params["_id"] = webhookID
|
params["_id"] = webhookID
|
||||||
|
query := fmt.Sprintf(`SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE _id=$_id LIMIT 1`, p.scopeName, models.Collections.Webhook)
|
||||||
query := fmt.Sprintf(`SELECT _id, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE _id=$_id LIMIT 1`, p.scopeName, models.Collections.Webhook)
|
|
||||||
q, err := p.db.Query(query, &gocb.QueryOptions{
|
q, err := p.db.Query(query, &gocb.QueryOptions{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
||||||
@@ -124,42 +120,42 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = q.One(&webhook)
|
err = q.One(&webhook)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
|
||||||
params := make(map[string]interface{}, 1)
|
params := make(map[string]interface{}, 1)
|
||||||
params["event_name"] = eventName
|
// params["event_name"] = eventName + "%"
|
||||||
|
query := fmt.Sprintf(`SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE event_name LIKE '%s'`, p.scopeName, models.Collections.Webhook, eventName+"%")
|
||||||
query := fmt.Sprintf(`SELECT _id, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE event_name=$event_name LIMIT 1`, p.scopeName, models.Collections.Webhook)
|
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
|
||||||
q, err := p.db.Query(query, &gocb.QueryOptions{
|
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
|
||||||
NamedParameters: params,
|
NamedParameters: params,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = q.One(&webhook)
|
webhooks := []*model.Webhook{}
|
||||||
|
for queryResult.Next() {
|
||||||
|
var webhook models.Webhook
|
||||||
|
err := queryResult.Row(&webhook)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
||||||
|
}
|
||||||
|
if err := queryResult.Err(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return webhooks, nil
|
||||||
return webhook.AsAPIWebhook(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
|
func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
|
||||||
|
|
||||||
params := make(map[string]interface{}, 1)
|
params := make(map[string]interface{}, 1)
|
||||||
params["webhook_id"] = webhook.ID
|
params["webhook_id"] = webhook.ID
|
||||||
removeOpt := gocb.RemoveOptions{
|
removeOpt := gocb.RemoveOptions{
|
||||||
|
@@ -3,28 +3,29 @@ package dynamodb
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/guregu/dynamo"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/guregu/dynamo"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AddWebhook to add webhook
|
// AddWebhook to add webhook
|
||||||
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
collection := p.db.Table(models.Collections.Webhook)
|
collection := p.db.Table(models.Collections.Webhook)
|
||||||
|
|
||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
err := collection.Put(webhook).RunWithContext(ctx)
|
err := collection.Put(webhook).RunWithContext(ctx)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -33,11 +34,13 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
|||||||
|
|
||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
collection := p.db.Table(models.Collections.Webhook)
|
|
||||||
|
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
|
collection := p.db.Table(models.Collections.Webhook)
|
||||||
err := UpdateByHashKey(collection, "id", webhook.ID, webhook)
|
err := UpdateByHashKey(collection, "id", webhook.ID, webhook)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -51,16 +54,13 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
|||||||
var lastEval dynamo.PagingKey
|
var lastEval dynamo.PagingKey
|
||||||
var iter dynamo.PagingIter
|
var iter dynamo.PagingIter
|
||||||
var iteration int64 = 0
|
var iteration int64 = 0
|
||||||
|
|
||||||
collection := p.db.Table(models.Collections.Webhook)
|
collection := p.db.Table(models.Collections.Webhook)
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
scanner := collection.Scan()
|
scanner := collection.Scan()
|
||||||
count, err := scanner.Count()
|
count, err := scanner.Count()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for (paginationClone.Offset + paginationClone.Limit) > iteration {
|
for (paginationClone.Offset + paginationClone.Limit) > iteration {
|
||||||
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
|
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
|
||||||
for iter.NextWithContext(ctx, &webhook) {
|
for iter.NextWithContext(ctx, &webhook) {
|
||||||
@@ -75,9 +75,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
|||||||
lastEval = iter.LastEvaluatedKey()
|
lastEval = iter.LastEvaluatedKey()
|
||||||
iteration += paginationClone.Limit
|
iteration += paginationClone.Limit
|
||||||
}
|
}
|
||||||
|
|
||||||
paginationClone.Total = count
|
paginationClone.Total = count
|
||||||
|
|
||||||
return &model.Webhooks{
|
return &model.Webhooks{
|
||||||
Pagination: &paginationClone,
|
Pagination: &paginationClone,
|
||||||
Webhooks: webhooks,
|
Webhooks: webhooks,
|
||||||
@@ -88,37 +86,29 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
|||||||
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
|
||||||
collection := p.db.Table(models.Collections.Webhook)
|
collection := p.db.Table(models.Collections.Webhook)
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
|
|
||||||
err := collection.Get("id", webhookID).OneWithContext(ctx, &webhook)
|
err := collection.Get("id", webhookID).OneWithContext(ctx, &webhook)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
return webhook.AsAPIWebhook(), errors.New("no documets found")
|
return webhook.AsAPIWebhook(), errors.New("no documets found")
|
||||||
}
|
}
|
||||||
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
webhooks := []models.Webhook{}
|
||||||
collection := p.db.Table(models.Collections.Webhook)
|
collection := p.db.Table(models.Collections.Webhook)
|
||||||
|
err := collection.Scan().Index("event_name").Filter("contains(event_name, ?)", eventName).AllWithContext(ctx, &webhooks)
|
||||||
iter := collection.Scan().Index("event_name").Filter("'event_name' = ?", eventName).Iter()
|
|
||||||
|
|
||||||
for iter.NextWithContext(ctx, &webhook) {
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err := iter.Err()
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return webhook.AsAPIWebhook(), err
|
return nil, err
|
||||||
}
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
resWebhooks := []*model.Webhook{}
|
||||||
|
for _, w := range webhooks {
|
||||||
|
resWebhooks = append(resWebhooks, w.AsAPIWebhook())
|
||||||
|
}
|
||||||
|
return resWebhooks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
@@ -133,7 +123,6 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
webhookLogs, errIs := p.ListWebhookLogs(ctx, pagination, webhook.ID)
|
webhookLogs, errIs := p.ListWebhookLogs(ctx, pagination, webhook.ID)
|
||||||
|
|
||||||
for _, webhookLog := range webhookLogs.WebhookLogs {
|
for _, webhookLog := range webhookLogs.WebhookLogs {
|
||||||
err = webhookLogCollection.Delete("id", webhookLog.ID).RunWithContext(ctx)
|
err = webhookLogCollection.Delete("id", webhookLog.ID).RunWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -2,6 +2,8 @@ package mongodb
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
@@ -16,11 +18,11 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
|||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
||||||
_, err := webhookCollection.InsertOne(ctx, webhook)
|
_, err := webhookCollection.InsertOne(ctx, webhook)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -32,39 +34,37 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
|||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
||||||
_, err := webhookCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": webhook.ID}}, bson.M{"$set": webhook}, options.MergeUpdateOptions())
|
_, err := webhookCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": webhook.ID}}, bson.M{"$set": webhook}, options.MergeUpdateOptions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListWebhooks to list webhook
|
// ListWebhooks to list webhook
|
||||||
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
||||||
var webhooks []*model.Webhook
|
webhooks := []*model.Webhook{}
|
||||||
opts := options.Find()
|
opts := options.Find()
|
||||||
opts.SetLimit(pagination.Limit)
|
opts.SetLimit(pagination.Limit)
|
||||||
opts.SetSkip(pagination.Offset)
|
opts.SetSkip(pagination.Offset)
|
||||||
opts.SetSort(bson.M{"created_at": -1})
|
opts.SetSort(bson.M{"created_at": -1})
|
||||||
|
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
|
|
||||||
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
||||||
count, err := webhookCollection.CountDocuments(ctx, bson.M{}, options.Count())
|
count, err := webhookCollection.CountDocuments(ctx, bson.M{}, options.Count())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
paginationClone.Total = count
|
paginationClone.Total = count
|
||||||
|
|
||||||
cursor, err := webhookCollection.Find(ctx, bson.M{}, opts)
|
cursor, err := webhookCollection.Find(ctx, bson.M{}, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer cursor.Close(ctx)
|
defer cursor.Close(ctx)
|
||||||
|
|
||||||
for cursor.Next(ctx) {
|
for cursor.Next(ctx) {
|
||||||
var webhook models.Webhook
|
var webhook models.Webhook
|
||||||
err := cursor.Decode(&webhook)
|
err := cursor.Decode(&webhook)
|
||||||
@@ -73,7 +73,6 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
|
|||||||
}
|
}
|
||||||
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
||||||
}
|
}
|
||||||
|
|
||||||
return &model.Webhooks{
|
return &model.Webhooks{
|
||||||
Pagination: &paginationClone,
|
Pagination: &paginationClone,
|
||||||
Webhooks: webhooks,
|
Webhooks: webhooks,
|
||||||
@@ -92,14 +91,27 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
webhooks := []*model.Webhook{}
|
||||||
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
|
||||||
err := webhookCollection.FindOne(ctx, bson.M{"event_name": eventName}).Decode(&webhook)
|
opts := options.Find()
|
||||||
|
opts.SetSort(bson.M{"created_at": -1})
|
||||||
|
cursor, err := webhookCollection.Find(ctx, bson.M{"event_name": bson.M{
|
||||||
|
"$regex": fmt.Sprintf("^%s", eventName),
|
||||||
|
}}, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
defer cursor.Close(ctx)
|
||||||
|
for cursor.Next(ctx) {
|
||||||
|
var webhook models.Webhook
|
||||||
|
err := cursor.Decode(&webhook)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
webhooks = append(webhooks, webhook.AsAPIWebhook())
|
||||||
|
}
|
||||||
|
return webhooks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
@@ -109,12 +121,10 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
webhookLogCollection := p.db.Collection(models.Collections.WebhookLog, options.Collection())
|
webhookLogCollection := p.db.Collection(models.Collections.WebhookLog, options.Collection())
|
||||||
_, err = webhookLogCollection.DeleteMany(nil, bson.M{"webhook_id": webhook.ID}, options.Delete())
|
_, err = webhookLogCollection.DeleteMany(nil, bson.M{"webhook_id": webhook.ID}, options.Delete())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,8 @@ package provider_template
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
@@ -14,16 +16,21 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
|||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,7 +45,7 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,7 +56,7 @@ type Provider interface {
|
|||||||
// GetWebhookByID to get webhook by id
|
// GetWebhookByID to get webhook by id
|
||||||
GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error)
|
GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error)
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error)
|
GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error)
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
DeleteWebhook(ctx context.Context, webhook *model.Webhook) error
|
DeleteWebhook(ctx context.Context, webhook *model.Webhook) error
|
||||||
|
|
||||||
|
@@ -2,6 +2,8 @@ package sql
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
@@ -14,10 +16,11 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
|||||||
if webhook.ID == "" {
|
if webhook.ID == "" {
|
||||||
webhook.ID = uuid.New().String()
|
webhook.ID = uuid.New().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook.Key = webhook.ID
|
webhook.Key = webhook.ID
|
||||||
webhook.CreatedAt = time.Now().Unix()
|
webhook.CreatedAt = time.Now().Unix()
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Add timestamp to make event name unique for legacy version
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
res := p.db.Create(&webhook)
|
res := p.db.Create(&webhook)
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
return nil, res.Error
|
return nil, res.Error
|
||||||
@@ -28,33 +31,31 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
|
|||||||
// UpdateWebhook to update webhook
|
// UpdateWebhook to update webhook
|
||||||
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
|
||||||
webhook.UpdatedAt = time.Now().Unix()
|
webhook.UpdatedAt = time.Now().Unix()
|
||||||
|
// Event is changed
|
||||||
|
if !strings.Contains(webhook.EventName, "-") {
|
||||||
|
webhook.EventName = fmt.Sprintf("%s-%d", webhook.EventName, time.Now().Unix())
|
||||||
|
}
|
||||||
result := p.db.Save(&webhook)
|
result := p.db.Save(&webhook)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
return webhook.AsAPIWebhook(), nil
|
return webhook.AsAPIWebhook(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListWebhooks to list webhook
|
// ListWebhooks to list webhook
|
||||||
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
|
||||||
var webhooks []models.Webhook
|
var webhooks []models.Webhook
|
||||||
|
|
||||||
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&webhooks)
|
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&webhooks)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
var total int64
|
var total int64
|
||||||
totalRes := p.db.Model(&models.Webhook{}).Count(&total)
|
totalRes := p.db.Model(&models.Webhook{}).Count(&total)
|
||||||
if totalRes.Error != nil {
|
if totalRes.Error != nil {
|
||||||
return nil, totalRes.Error
|
return nil, totalRes.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
paginationClone := pagination
|
paginationClone := pagination
|
||||||
paginationClone.Total = total
|
paginationClone.Total = total
|
||||||
|
|
||||||
responseWebhooks := []*model.Webhook{}
|
responseWebhooks := []*model.Webhook{}
|
||||||
for _, w := range webhooks {
|
for _, w := range webhooks {
|
||||||
responseWebhooks = append(responseWebhooks, w.AsAPIWebhook())
|
responseWebhooks = append(responseWebhooks, w.AsAPIWebhook())
|
||||||
@@ -77,14 +78,17 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetWebhookByEventName to get webhook by event_name
|
// GetWebhookByEventName to get webhook by event_name
|
||||||
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) (*model.Webhook, error) {
|
func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string) ([]*model.Webhook, error) {
|
||||||
var webhook models.Webhook
|
var webhooks []models.Webhook
|
||||||
|
result := p.db.Where("event_name LIKE ?", eventName+"%").Find(&webhooks)
|
||||||
result := p.db.Where("event_name = ?", eventName).First(&webhook)
|
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
return nil, result.Error
|
return nil, result.Error
|
||||||
}
|
}
|
||||||
return webhook.AsAPIWebhook(), nil
|
responseWebhooks := []*model.Webhook{}
|
||||||
|
for _, w := range webhooks {
|
||||||
|
responseWebhooks = append(responseWebhooks, w.AsAPIWebhook())
|
||||||
|
}
|
||||||
|
return responseWebhooks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteWebhook to delete webhook
|
// DeleteWebhook to delete webhook
|
||||||
|
@@ -278,6 +278,7 @@ type ComplexityRoot struct {
|
|||||||
CreatedAt func(childComplexity int) int
|
CreatedAt func(childComplexity int) int
|
||||||
Enabled func(childComplexity int) int
|
Enabled func(childComplexity int) int
|
||||||
Endpoint func(childComplexity int) int
|
Endpoint func(childComplexity int) int
|
||||||
|
EventDescription func(childComplexity int) int
|
||||||
EventName func(childComplexity int) int
|
EventName func(childComplexity int) int
|
||||||
Headers func(childComplexity int) int
|
Headers func(childComplexity int) int
|
||||||
ID func(childComplexity int) int
|
ID func(childComplexity int) int
|
||||||
@@ -1833,6 +1834,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||||||
|
|
||||||
return e.complexity.Webhook.Endpoint(childComplexity), true
|
return e.complexity.Webhook.Endpoint(childComplexity), true
|
||||||
|
|
||||||
|
case "Webhook.event_description":
|
||||||
|
if e.complexity.Webhook.EventDescription == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Webhook.EventDescription(childComplexity), true
|
||||||
|
|
||||||
case "Webhook.event_name":
|
case "Webhook.event_name":
|
||||||
if e.complexity.Webhook.EventName == nil {
|
if e.complexity.Webhook.EventName == nil {
|
||||||
break
|
break
|
||||||
@@ -2210,7 +2218,8 @@ type GenerateJWTKeysResponse {
|
|||||||
|
|
||||||
type Webhook {
|
type Webhook {
|
||||||
id: ID!
|
id: ID!
|
||||||
event_name: String
|
event_name: String # this is unique string
|
||||||
|
event_description: String
|
||||||
endpoint: String
|
endpoint: String
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
headers: Map
|
headers: Map
|
||||||
@@ -2501,6 +2510,7 @@ input ListWebhookLogRequest {
|
|||||||
|
|
||||||
input AddWebhookRequest {
|
input AddWebhookRequest {
|
||||||
event_name: String!
|
event_name: String!
|
||||||
|
event_description: String
|
||||||
endpoint: String!
|
endpoint: String!
|
||||||
enabled: Boolean!
|
enabled: Boolean!
|
||||||
headers: Map
|
headers: Map
|
||||||
@@ -2509,6 +2519,7 @@ input AddWebhookRequest {
|
|||||||
input UpdateWebhookRequest {
|
input UpdateWebhookRequest {
|
||||||
id: ID!
|
id: ID!
|
||||||
event_name: String
|
event_name: String
|
||||||
|
event_description: String
|
||||||
endpoint: String
|
endpoint: String
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
headers: Map
|
headers: Map
|
||||||
@@ -10143,6 +10154,8 @@ func (ec *executionContext) fieldContext_Query__webhook(ctx context.Context, fie
|
|||||||
return ec.fieldContext_Webhook_id(ctx, field)
|
return ec.fieldContext_Webhook_id(ctx, field)
|
||||||
case "event_name":
|
case "event_name":
|
||||||
return ec.fieldContext_Webhook_event_name(ctx, field)
|
return ec.fieldContext_Webhook_event_name(ctx, field)
|
||||||
|
case "event_description":
|
||||||
|
return ec.fieldContext_Webhook_event_description(ctx, field)
|
||||||
case "endpoint":
|
case "endpoint":
|
||||||
return ec.fieldContext_Webhook_endpoint(ctx, field)
|
return ec.fieldContext_Webhook_endpoint(ctx, field)
|
||||||
case "enabled":
|
case "enabled":
|
||||||
@@ -12201,6 +12214,47 @@ func (ec *executionContext) fieldContext_Webhook_event_name(ctx context.Context,
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Webhook_event_description(ctx context.Context, field graphql.CollectedField, obj *model.Webhook) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Webhook_event_description(ctx, field)
|
||||||
|
if err != nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
|
ctx = rctx // use context from middleware stack in children
|
||||||
|
return obj.EventDescription, nil
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.(*string)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Webhook_event_description(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Webhook",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: false,
|
||||||
|
IsResolver: false,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return nil, errors.New("field of type String does not have child fields")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Webhook_endpoint(ctx context.Context, field graphql.CollectedField, obj *model.Webhook) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Webhook_endpoint(ctx context.Context, field graphql.CollectedField, obj *model.Webhook) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_Webhook_endpoint(ctx, field)
|
fc, err := ec.fieldContext_Webhook_endpoint(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -12907,6 +12961,8 @@ func (ec *executionContext) fieldContext_Webhooks_webhooks(ctx context.Context,
|
|||||||
return ec.fieldContext_Webhook_id(ctx, field)
|
return ec.fieldContext_Webhook_id(ctx, field)
|
||||||
case "event_name":
|
case "event_name":
|
||||||
return ec.fieldContext_Webhook_event_name(ctx, field)
|
return ec.fieldContext_Webhook_event_name(ctx, field)
|
||||||
|
case "event_description":
|
||||||
|
return ec.fieldContext_Webhook_event_description(ctx, field)
|
||||||
case "endpoint":
|
case "endpoint":
|
||||||
return ec.fieldContext_Webhook_endpoint(ctx, field)
|
return ec.fieldContext_Webhook_endpoint(ctx, field)
|
||||||
case "enabled":
|
case "enabled":
|
||||||
@@ -14756,7 +14812,7 @@ func (ec *executionContext) unmarshalInputAddWebhookRequest(ctx context.Context,
|
|||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"event_name", "endpoint", "enabled", "headers"}
|
fieldsInOrder := [...]string{"event_name", "event_description", "endpoint", "enabled", "headers"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -14771,6 +14827,14 @@ func (ec *executionContext) unmarshalInputAddWebhookRequest(ctx context.Context,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
|
case "event_description":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("event_description"))
|
||||||
|
it.EventDescription, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
case "endpoint":
|
case "endpoint":
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -16612,7 +16676,7 @@ func (ec *executionContext) unmarshalInputUpdateWebhookRequest(ctx context.Conte
|
|||||||
asMap[k] = v
|
asMap[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldsInOrder := [...]string{"id", "event_name", "endpoint", "enabled", "headers"}
|
fieldsInOrder := [...]string{"id", "event_name", "event_description", "endpoint", "enabled", "headers"}
|
||||||
for _, k := range fieldsInOrder {
|
for _, k := range fieldsInOrder {
|
||||||
v, ok := asMap[k]
|
v, ok := asMap[k]
|
||||||
if !ok {
|
if !ok {
|
||||||
@@ -16635,6 +16699,14 @@ func (ec *executionContext) unmarshalInputUpdateWebhookRequest(ctx context.Conte
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
|
case "event_description":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("event_description"))
|
||||||
|
it.EventDescription, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
case "endpoint":
|
case "endpoint":
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -18513,6 +18585,10 @@ func (ec *executionContext) _Webhook(ctx context.Context, sel ast.SelectionSet,
|
|||||||
|
|
||||||
out.Values[i] = ec._Webhook_event_name(ctx, field, obj)
|
out.Values[i] = ec._Webhook_event_name(ctx, field, obj)
|
||||||
|
|
||||||
|
case "event_description":
|
||||||
|
|
||||||
|
out.Values[i] = ec._Webhook_event_description(ctx, field, obj)
|
||||||
|
|
||||||
case "endpoint":
|
case "endpoint":
|
||||||
|
|
||||||
out.Values[i] = ec._Webhook_endpoint(ctx, field, obj)
|
out.Values[i] = ec._Webhook_endpoint(ctx, field, obj)
|
||||||
|
@@ -11,6 +11,7 @@ type AddEmailTemplateRequest struct {
|
|||||||
|
|
||||||
type AddWebhookRequest struct {
|
type AddWebhookRequest struct {
|
||||||
EventName string `json:"event_name"`
|
EventName string `json:"event_name"`
|
||||||
|
EventDescription *string `json:"event_description"`
|
||||||
Endpoint string `json:"endpoint"`
|
Endpoint string `json:"endpoint"`
|
||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
Headers map[string]interface{} `json:"headers"`
|
Headers map[string]interface{} `json:"headers"`
|
||||||
@@ -389,6 +390,7 @@ type UpdateUserInput struct {
|
|||||||
type UpdateWebhookRequest struct {
|
type UpdateWebhookRequest struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
EventName *string `json:"event_name"`
|
EventName *string `json:"event_name"`
|
||||||
|
EventDescription *string `json:"event_description"`
|
||||||
Endpoint *string `json:"endpoint"`
|
Endpoint *string `json:"endpoint"`
|
||||||
Enabled *bool `json:"enabled"`
|
Enabled *bool `json:"enabled"`
|
||||||
Headers map[string]interface{} `json:"headers"`
|
Headers map[string]interface{} `json:"headers"`
|
||||||
@@ -463,6 +465,7 @@ type VerifyOTPRequest struct {
|
|||||||
type Webhook struct {
|
type Webhook struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
EventName *string `json:"event_name"`
|
EventName *string `json:"event_name"`
|
||||||
|
EventDescription *string `json:"event_description"`
|
||||||
Endpoint *string `json:"endpoint"`
|
Endpoint *string `json:"endpoint"`
|
||||||
Enabled *bool `json:"enabled"`
|
Enabled *bool `json:"enabled"`
|
||||||
Headers map[string]interface{} `json:"headers"`
|
Headers map[string]interface{} `json:"headers"`
|
||||||
|
@@ -168,7 +168,8 @@ type GenerateJWTKeysResponse {
|
|||||||
|
|
||||||
type Webhook {
|
type Webhook {
|
||||||
id: ID!
|
id: ID!
|
||||||
event_name: String
|
event_name: String # this is unique string
|
||||||
|
event_description: String
|
||||||
endpoint: String
|
endpoint: String
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
headers: Map
|
headers: Map
|
||||||
@@ -459,6 +460,7 @@ input ListWebhookLogRequest {
|
|||||||
|
|
||||||
input AddWebhookRequest {
|
input AddWebhookRequest {
|
||||||
event_name: String!
|
event_name: String!
|
||||||
|
event_description: String
|
||||||
endpoint: String!
|
endpoint: String!
|
||||||
enabled: Boolean!
|
enabled: Boolean!
|
||||||
headers: Map
|
headers: Map
|
||||||
@@ -467,6 +469,7 @@ input AddWebhookRequest {
|
|||||||
input UpdateWebhookRequest {
|
input UpdateWebhookRequest {
|
||||||
id: ID!
|
id: ID!
|
||||||
event_name: String
|
event_name: String
|
||||||
|
event_description: String
|
||||||
endpoint: String
|
endpoint: String
|
||||||
enabled: Boolean
|
enabled: Boolean
|
||||||
headers: Map
|
headers: Map
|
||||||
|
@@ -2,7 +2,7 @@ package handlers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/99designs/gqlgen/graphql/handler"
|
"github.com/99designs/gqlgen/graphql/handler"
|
||||||
graph "github.com/authorizerdev/authorizer/server/graph"
|
"github.com/authorizerdev/authorizer/server/graph"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/generated"
|
"github.com/authorizerdev/authorizer/server/graph/generated"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
@@ -27,10 +27,8 @@ func JWKsHandler() gin.HandlerFunc {
|
|||||||
c.JSON(500, gin.H{
|
c.JSON(500, gin.H{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
c.JSON(200, gin.H{
|
c.JSON(200, gin.H{
|
||||||
"keys": []map[string]string{
|
"keys": []map[string]string{
|
||||||
data,
|
data,
|
||||||
|
@@ -20,9 +20,11 @@ func OpenIDConfigurationHandler() gin.HandlerFunc {
|
|||||||
"token_endpoint": issuer + "/oauth/token",
|
"token_endpoint": issuer + "/oauth/token",
|
||||||
"userinfo_endpoint": issuer + "/userinfo",
|
"userinfo_endpoint": issuer + "/userinfo",
|
||||||
"jwks_uri": issuer + "/.well-known/jwks.json",
|
"jwks_uri": issuer + "/.well-known/jwks.json",
|
||||||
|
"registration_endpoint": issuer + "/app",
|
||||||
"response_types_supported": []string{"code", "token", "id_token"},
|
"response_types_supported": []string{"code", "token", "id_token"},
|
||||||
"scopes_supported": []string{"openid", "email", "profile", "email_verified", "given_name", "family_name", "nick_name", "picture"},
|
"scopes_supported": []string{"openid", "email", "profile"},
|
||||||
"response_modes_supported": []string{"query", "fragment", "form_post", "web_message"},
|
"response_modes_supported": []string{"query", "fragment", "form_post", "web_message"},
|
||||||
|
"subject_types_supported": "public",
|
||||||
"id_token_signing_alg_values_supported": []string{jwtType},
|
"id_token_signing_alg_values_supported": []string{jwtType},
|
||||||
"claims_supported": []string{"aud", "exp", "iss", "iat", "sub", "given_name", "family_name", "middle_name", "nickname", "preferred_username", "picture", "email", "email_verified", "roles", "role", "gender", "birthdate", "phone_number", "phone_number_verified", "nonce", "updated_at", "created_at", "revoked_timestamp", "login_method", "signup_methods", "token_type"},
|
"claims_supported": []string{"aud", "exp", "iss", "iat", "sub", "given_name", "family_name", "middle_name", "nickname", "preferred_username", "picture", "email", "email_verified", "roles", "role", "gender", "birthdate", "phone_number", "phone_number_verified", "nonce", "updated_at", "created_at", "revoked_timestamp", "login_method", "signup_methods", "token_type"},
|
||||||
})
|
})
|
||||||
|
@@ -2,7 +2,6 @@ package handlers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -50,7 +49,6 @@ func UserInfoHandler() gin.HandlerFunc {
|
|||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Println("=> str:", string(userBytes))
|
|
||||||
res := map[string]interface{}{}
|
res := map[string]interface{}{}
|
||||||
err = json.Unmarshal(userBytes, &res)
|
err = json.Unmarshal(userBytes, &res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@@ -9,6 +9,7 @@ import (
|
|||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
|
"github.com/authorizerdev/authorizer/server/refs"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
"github.com/authorizerdev/authorizer/server/validators"
|
"github.com/authorizerdev/authorizer/server/validators"
|
||||||
@@ -22,28 +23,28 @@ func AddWebhookResolver(ctx context.Context, params model.AddWebhookRequest) (*m
|
|||||||
log.Debug("Failed to get GinContext: ", err)
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !token.IsSuperAdmin(gc) {
|
if !token.IsSuperAdmin(gc) {
|
||||||
log.Debug("Not logged in as super admin")
|
log.Debug("Not logged in as super admin")
|
||||||
return nil, fmt.Errorf("unauthorized")
|
return nil, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !validators.IsValidWebhookEventName(params.EventName) {
|
if !validators.IsValidWebhookEventName(params.EventName) {
|
||||||
log.Debug("Invalid Event Name: ", params.EventName)
|
log.Debug("Invalid Event Name: ", params.EventName)
|
||||||
return nil, fmt.Errorf("invalid event name %s", params.EventName)
|
return nil, fmt.Errorf("invalid event name %s", params.EventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(params.Endpoint) == "" {
|
if strings.TrimSpace(params.Endpoint) == "" {
|
||||||
log.Debug("empty endpoint not allowed")
|
log.Debug("empty endpoint not allowed")
|
||||||
return nil, fmt.Errorf("empty endpoint not allowed")
|
return nil, fmt.Errorf("empty endpoint not allowed")
|
||||||
}
|
}
|
||||||
|
|
||||||
headerBytes, err := json.Marshal(params.Headers)
|
headerBytes, err := json.Marshal(params.Headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if params.EventDescription == nil {
|
||||||
|
params.EventDescription = refs.NewStringRef(strings.Join(strings.Split(params.EventName, "."), " "))
|
||||||
|
}
|
||||||
_, err = db.Provider.AddWebhook(ctx, models.Webhook{
|
_, err = db.Provider.AddWebhook(ctx, models.Webhook{
|
||||||
|
EventDescription: refs.StringValue(params.EventDescription),
|
||||||
EventName: params.EventName,
|
EventName: params.EventName,
|
||||||
EndPoint: params.Endpoint,
|
EndPoint: params.Endpoint,
|
||||||
Enabled: params.Enabled,
|
Enabled: params.Enabled,
|
||||||
|
@@ -28,13 +28,11 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
|
|||||||
log.Debug("Not logged in as super admin")
|
log.Debug("Not logged in as super admin")
|
||||||
return nil, fmt.Errorf("unauthorized")
|
return nil, fmt.Errorf("unauthorized")
|
||||||
}
|
}
|
||||||
|
|
||||||
webhook, err := db.Provider.GetWebhookByID(ctx, params.ID)
|
webhook, err := db.Provider.GetWebhookByID(ctx, params.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("failed to get webhook: ", err)
|
log.Debug("failed to get webhook: ", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
headersString := ""
|
headersString := ""
|
||||||
if webhook.Headers != nil {
|
if webhook.Headers != nil {
|
||||||
headerBytes, err := json.Marshal(webhook.Headers)
|
headerBytes, err := json.Marshal(webhook.Headers)
|
||||||
@@ -43,17 +41,16 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
|
|||||||
}
|
}
|
||||||
headersString = string(headerBytes)
|
headersString = string(headerBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
webhookDetails := models.Webhook{
|
webhookDetails := models.Webhook{
|
||||||
ID: webhook.ID,
|
ID: webhook.ID,
|
||||||
Key: webhook.ID,
|
Key: webhook.ID,
|
||||||
EventName: refs.StringValue(webhook.EventName),
|
EventName: refs.StringValue(webhook.EventName),
|
||||||
|
EventDescription: refs.StringValue(webhook.EventDescription),
|
||||||
EndPoint: refs.StringValue(webhook.Endpoint),
|
EndPoint: refs.StringValue(webhook.Endpoint),
|
||||||
Enabled: refs.BoolValue(webhook.Enabled),
|
Enabled: refs.BoolValue(webhook.Enabled),
|
||||||
Headers: headersString,
|
Headers: headersString,
|
||||||
CreatedAt: refs.Int64Value(webhook.CreatedAt),
|
CreatedAt: refs.Int64Value(webhook.CreatedAt),
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.EventName != nil && webhookDetails.EventName != refs.StringValue(params.EventName) {
|
if params.EventName != nil && webhookDetails.EventName != refs.StringValue(params.EventName) {
|
||||||
if isValid := validators.IsValidWebhookEventName(refs.StringValue(params.EventName)); !isValid {
|
if isValid := validators.IsValidWebhookEventName(refs.StringValue(params.EventName)); !isValid {
|
||||||
log.Debug("invalid event name: ", refs.StringValue(params.EventName))
|
log.Debug("invalid event name: ", refs.StringValue(params.EventName))
|
||||||
@@ -61,7 +58,6 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
|
|||||||
}
|
}
|
||||||
webhookDetails.EventName = refs.StringValue(params.EventName)
|
webhookDetails.EventName = refs.StringValue(params.EventName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.Endpoint != nil && webhookDetails.EndPoint != refs.StringValue(params.Endpoint) {
|
if params.Endpoint != nil && webhookDetails.EndPoint != refs.StringValue(params.Endpoint) {
|
||||||
if strings.TrimSpace(refs.StringValue(params.Endpoint)) == "" {
|
if strings.TrimSpace(refs.StringValue(params.Endpoint)) == "" {
|
||||||
log.Debug("empty endpoint not allowed")
|
log.Debug("empty endpoint not allowed")
|
||||||
@@ -69,11 +65,12 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
|
|||||||
}
|
}
|
||||||
webhookDetails.EndPoint = refs.StringValue(params.Endpoint)
|
webhookDetails.EndPoint = refs.StringValue(params.Endpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
if params.Enabled != nil && webhookDetails.Enabled != refs.BoolValue(params.Enabled) {
|
if params.Enabled != nil && webhookDetails.Enabled != refs.BoolValue(params.Enabled) {
|
||||||
webhookDetails.Enabled = refs.BoolValue(params.Enabled)
|
webhookDetails.Enabled = refs.BoolValue(params.Enabled)
|
||||||
}
|
}
|
||||||
|
if params.EventDescription != nil && webhookDetails.EventDescription != refs.StringValue(params.EventDescription) {
|
||||||
|
webhookDetails.EventDescription = refs.StringValue(params.EventDescription)
|
||||||
|
}
|
||||||
if params.Headers != nil {
|
if params.Headers != nil {
|
||||||
headerBytes, err := json.Marshal(params.Headers)
|
headerBytes, err := json.Marshal(params.Headers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -83,12 +80,10 @@ func UpdateWebhookResolver(ctx context.Context, params model.UpdateWebhookReques
|
|||||||
|
|
||||||
webhookDetails.Headers = string(headerBytes)
|
webhookDetails.Headers = string(headerBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = db.Provider.UpdateWebhook(ctx, webhookDetails)
|
_, err = db.Provider.UpdateWebhook(ctx, webhookDetails)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &model.Response{
|
return &model.Response{
|
||||||
Message: `Webhook updated successfully.`,
|
Message: `Webhook updated successfully.`,
|
||||||
}, nil
|
}, nil
|
||||||
|
@@ -3,11 +3,13 @@ package test
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/memorystore"
|
"github.com/authorizerdev/authorizer/server/memorystore"
|
||||||
|
"github.com/authorizerdev/authorizer/server/refs"
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@@ -21,7 +23,6 @@ func addWebhookTest(t *testing.T, s TestSetup) {
|
|||||||
h, err := crypto.EncryptPassword(adminSecret)
|
h, err := crypto.EncryptPassword(adminSecret)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
||||||
|
|
||||||
for _, eventType := range s.TestInfo.TestWebhookEventTypes {
|
for _, eventType := range s.TestInfo.TestWebhookEventTypes {
|
||||||
webhook, err := resolvers.AddWebhookResolver(ctx, model.AddWebhookRequest{
|
webhook, err := resolvers.AddWebhookResolver(ctx, model.AddWebhookRequest{
|
||||||
EventName: eventType,
|
EventName: eventType,
|
||||||
@@ -35,5 +36,21 @@ func addWebhookTest(t *testing.T, s TestSetup) {
|
|||||||
assert.NotNil(t, webhook)
|
assert.NotNil(t, webhook)
|
||||||
assert.NotEmpty(t, webhook.Message)
|
assert.NotEmpty(t, webhook.Message)
|
||||||
}
|
}
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
// Allow setting multiple webhooks for same event
|
||||||
|
for _, eventType := range s.TestInfo.TestWebhookEventTypes {
|
||||||
|
webhook, err := resolvers.AddWebhookResolver(ctx, model.AddWebhookRequest{
|
||||||
|
EventName: eventType,
|
||||||
|
Endpoint: s.TestInfo.WebhookEndpoint,
|
||||||
|
Enabled: true,
|
||||||
|
EventDescription: refs.NewStringRef(eventType + "-2"),
|
||||||
|
Headers: map[string]interface{}{
|
||||||
|
"x-test": "foo",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, webhook)
|
||||||
|
assert.NotEmpty(t, webhook.Message)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -25,6 +25,6 @@ func adminSignupTests(t *testing.T, s TestSetup) {
|
|||||||
_, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
_, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
||||||
AdminSecret: "admin123",
|
AdminSecret: "admin123",
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.NoError(t, err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,7 @@ func deleteWebhookTest(t *testing.T, s TestSetup) {
|
|||||||
|
|
||||||
// get all webhooks
|
// get all webhooks
|
||||||
webhooks, err := db.Provider.ListWebhook(ctx, model.Pagination{
|
webhooks, err := db.Provider.ListWebhook(ctx, model.Pagination{
|
||||||
Limit: 10,
|
Limit: 20,
|
||||||
Page: 1,
|
Page: 1,
|
||||||
Offset: 0,
|
Offset: 0,
|
||||||
})
|
})
|
||||||
@@ -42,7 +42,7 @@ func deleteWebhookTest(t *testing.T, s TestSetup) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
webhooks, err = db.Provider.ListWebhook(ctx, model.Pagination{
|
webhooks, err = db.Provider.ListWebhook(ctx, model.Pagination{
|
||||||
Limit: 10,
|
Limit: 20,
|
||||||
Page: 1,
|
Page: 1,
|
||||||
Offset: 0,
|
Offset: 0,
|
||||||
})
|
})
|
||||||
|
@@ -23,6 +23,8 @@ func enableAccessTest(t *testing.T, s TestSetup) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
@@ -15,17 +15,18 @@ func forgotPasswordTest(t *testing.T, s TestSetup) {
|
|||||||
t.Run(`should run forgot password`, func(t *testing.T) {
|
t.Run(`should run forgot password`, func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
email := "forgot_password." + s.TestInfo.Email
|
email := "forgot_password." + s.TestInfo.Email
|
||||||
_, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
_, err = resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
|
assert.NotNil(t, res)
|
||||||
|
forgotPasswordRes, err := resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err, "no errors for forgot password")
|
assert.Nil(t, err, "no errors for forgot password")
|
||||||
|
assert.NotNil(t, forgotPasswordRes)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
@@ -41,21 +41,20 @@ func inviteUserTest(t *testing.T, s TestSetup) {
|
|||||||
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
||||||
Emails: invalidEmailsTest,
|
Emails: invalidEmailsTest,
|
||||||
})
|
})
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
// valid test
|
// valid test
|
||||||
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
||||||
Emails: emails,
|
Emails: emails,
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.NotNil(t, res)
|
assert.NotNil(t, res)
|
||||||
|
|
||||||
// duplicate error test
|
// duplicate error test
|
||||||
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
|
||||||
Emails: emails,
|
Emails: emails,
|
||||||
})
|
})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Nil(t, res)
|
assert.Nil(t, res)
|
||||||
|
|
||||||
cleanData(emails[0])
|
cleanData(emails[0])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -16,12 +16,13 @@ func loginTests(t *testing.T, s TestSetup) {
|
|||||||
t.Run(`should login`, func(t *testing.T) {
|
t.Run(`should login`, func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
email := "login." + s.TestInfo.Email
|
email := "login." + s.TestInfo.Email
|
||||||
_, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
signUpRes, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, signUpRes)
|
||||||
res, err := resolvers.LoginResolver(ctx, model.LoginInput{
|
res, err := resolvers.LoginResolver(ctx, model.LoginInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
@@ -30,6 +31,8 @@ func loginTests(t *testing.T, s TestSetup) {
|
|||||||
assert.NotNil(t, err, "should fail because email is not verified")
|
assert.NotNil(t, err, "should fail because email is not verified")
|
||||||
assert.Nil(t, res)
|
assert.Nil(t, res)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
n, err := utils.EncryptNonce(verificationRequest.Nonce)
|
n, err := utils.EncryptNonce(verificationRequest.Nonce)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, n)
|
assert.NotEmpty(t, n)
|
||||||
|
@@ -20,22 +20,24 @@ func logoutTests(t *testing.T, s TestSetup) {
|
|||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
email := "logout." + s.TestInfo.Email
|
email := "logout." + s.TestInfo.Email
|
||||||
|
|
||||||
_, err := resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
|
magicLoginRes, err := resolvers.MagicLinkLoginResolver(ctx, model.MagicLinkLoginInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, magicLoginRes)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verifyRes)
|
||||||
accessToken := *verifyRes.AccessToken
|
accessToken := *verifyRes.AccessToken
|
||||||
assert.NotEmpty(t, accessToken)
|
assert.NotEmpty(t, accessToken)
|
||||||
|
|
||||||
claims, err := token.ParseJWTToken(accessToken)
|
claims, err := token.ParseJWTToken(accessToken)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, claims)
|
assert.NotEmpty(t, claims)
|
||||||
|
|
||||||
loginMethod := claims["login_method"]
|
loginMethod := claims["login_method"]
|
||||||
sessionKey := verifyRes.User.ID
|
sessionKey := verifyRes.User.ID
|
||||||
if loginMethod != nil && loginMethod != "" {
|
if loginMethod != nil && loginMethod != "" {
|
||||||
|
@@ -30,6 +30,8 @@ func magicLinkLoginTests(t *testing.T, s TestSetup) {
|
|||||||
assert.Nil(t, err, "signup should be successful")
|
assert.Nil(t, err, "signup should be successful")
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
@@ -29,24 +29,25 @@ func mobileSingupTest(t *testing.T, s TestSetup) {
|
|||||||
Password: "test",
|
Password: "test",
|
||||||
ConfirmPassword: "test",
|
ConfirmPassword: "test",
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid password")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
|
||||||
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
||||||
Email: refs.NewStringRef(email),
|
Email: refs.NewStringRef(email),
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "singup disabled")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
|
||||||
|
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication, true)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication, true)
|
||||||
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
||||||
Email: refs.NewStringRef(email),
|
Email: refs.NewStringRef(email),
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "singup disabled")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication, false)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication, false)
|
||||||
|
|
||||||
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
||||||
@@ -54,14 +55,16 @@ func mobileSingupTest(t *testing.T, s TestSetup) {
|
|||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid mobile")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
|
||||||
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
||||||
PhoneNumber: "test",
|
PhoneNumber: "test",
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid mobile")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
|
||||||
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
res, err = resolvers.MobileSignupResolver(ctx, &model.MobileSignUpInput{
|
||||||
PhoneNumber: "1234567890",
|
PhoneNumber: "1234567890",
|
||||||
@@ -77,7 +80,8 @@ func mobileSingupTest(t *testing.T, s TestSetup) {
|
|||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.Error(t, err, "user exists")
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
|
|
||||||
cleanData(email)
|
cleanData(email)
|
||||||
cleanData("1234567890@authorizer.dev")
|
cleanData("1234567890@authorizer.dev")
|
||||||
|
@@ -27,6 +27,8 @@ func profileTests(t *testing.T, s TestSetup) {
|
|||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
@@ -44,10 +44,11 @@ func resendOTPTest(t *testing.T, s TestSetup) {
|
|||||||
// Using access token update profile
|
// Using access token update profile
|
||||||
s.GinContext.Request.Header.Set("Authorization", "Bearer "+refs.StringValue(verifyRes.AccessToken))
|
s.GinContext.Request.Header.Set("Authorization", "Bearer "+refs.StringValue(verifyRes.AccessToken))
|
||||||
ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
|
ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
|
||||||
_, err = resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
|
updateRes, err := resolvers.UpdateProfileResolver(ctx, model.UpdateProfileInput{
|
||||||
IsMultiFactorAuthEnabled: refs.NewBoolRef(true),
|
IsMultiFactorAuthEnabled: refs.NewBoolRef(true),
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, updateRes)
|
||||||
// Resend otp should return error as no initial opt is being sent
|
// Resend otp should return error as no initial opt is being sent
|
||||||
resendOtpRes, err := resolvers.ResendOTPResolver(ctx, model.ResendOTPRequest{
|
resendOtpRes, err := resolvers.ResendOTPResolver(ctx, model.ResendOTPRequest{
|
||||||
Email: email,
|
Email: email,
|
||||||
@@ -87,7 +88,7 @@ func resendOTPTest(t *testing.T, s TestSetup) {
|
|||||||
Otp: otp.Otp,
|
Otp: otp.Otp,
|
||||||
})
|
})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, verifyOtpRes)
|
||||||
verifyOtpRes, err = resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
|
verifyOtpRes, err = resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
|
||||||
Email: email,
|
Email: email,
|
||||||
Otp: newOtp.Otp,
|
Otp: newOtp.Otp,
|
||||||
|
@@ -19,13 +19,12 @@ func resendVerifyEmailTests(t *testing.T, s TestSetup) {
|
|||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
_, err = resolvers.ResendVerifyEmailResolver(ctx, model.ResendVerifyEmailInput{
|
_, err = resolvers.ResendVerifyEmailResolver(ctx, model.ResendVerifyEmailInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Identifier: constants.VerificationTypeBasicAuthSignup,
|
Identifier: constants.VerificationTypeBasicAuthSignup,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
cleanData(email)
|
cleanData(email)
|
||||||
})
|
})
|
||||||
|
@@ -20,7 +20,7 @@ func resetPasswordTest(t *testing.T, s TestSetup) {
|
|||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
_, err = resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
|
_, err = resolvers.ForgotPasswordResolver(ctx, model.ForgotPasswordInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
})
|
})
|
||||||
@@ -28,7 +28,7 @@ func resetPasswordTest(t *testing.T, s TestSetup) {
|
|||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
||||||
assert.Nil(t, err, "should get forgot password request")
|
assert.Nil(t, err, "should get forgot password request")
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
_, err = resolvers.ResetPasswordResolver(ctx, model.ResetPasswordInput{
|
_, err = resolvers.ResetPasswordResolver(ctx, model.ResetPasswordInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
Password: "test1",
|
Password: "test1",
|
||||||
|
@@ -23,6 +23,8 @@ func revokeAccessTest(t *testing.T, s TestSetup) {
|
|||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
@@ -33,7 +35,7 @@ func revokeAccessTest(t *testing.T, s TestSetup) {
|
|||||||
UserID: verifyRes.User.ID,
|
UserID: verifyRes.User.ID,
|
||||||
})
|
})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
@@ -30,10 +30,13 @@ func sessionTests(t *testing.T, s TestSetup) {
|
|||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verifyRes)
|
||||||
accessToken := *verifyRes.AccessToken
|
accessToken := *verifyRes.AccessToken
|
||||||
assert.NotEmpty(t, accessToken)
|
assert.NotEmpty(t, accessToken)
|
||||||
|
|
||||||
|
@@ -22,14 +22,14 @@ func signupTests(t *testing.T, s TestSetup) {
|
|||||||
ConfirmPassword: s.TestInfo.Password + "s",
|
ConfirmPassword: s.TestInfo.Password + "s",
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid password")
|
assert.NotNil(t, err, "invalid password")
|
||||||
|
assert.Nil(t, res)
|
||||||
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: "test",
|
Password: "test",
|
||||||
ConfirmPassword: "test",
|
ConfirmPassword: "test",
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "invalid password")
|
assert.NotNil(t, err, "invalid password")
|
||||||
|
assert.Nil(t, res)
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, true)
|
||||||
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
@@ -37,7 +37,7 @@ func signupTests(t *testing.T, s TestSetup) {
|
|||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
assert.NotNil(t, err, "singup disabled")
|
assert.NotNil(t, err, "singup disabled")
|
||||||
|
assert.Nil(t, res)
|
||||||
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
|
memorystore.Provider.UpdateEnvVariable(constants.EnvKeyDisableSignUp, false)
|
||||||
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
@@ -48,15 +48,13 @@ func signupTests(t *testing.T, s TestSetup) {
|
|||||||
user := *res.User
|
user := *res.User
|
||||||
assert.Equal(t, email, user.Email)
|
assert.Equal(t, email, user.Email)
|
||||||
assert.Nil(t, res.AccessToken, "access token should be nil")
|
assert.Nil(t, res.AccessToken, "access token should be nil")
|
||||||
|
|
||||||
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err = resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NotNil(t, err, "should throw duplicate email error")
|
assert.NotNil(t, err, "should throw duplicate email error")
|
||||||
|
assert.Nil(t, res)
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, email, verificationRequest.Email)
|
assert.Equal(t, email, verificationRequest.Email)
|
||||||
|
@@ -40,31 +40,49 @@ func cleanData(email string) {
|
|||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteVerificationRequest err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeForgotPassword)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteVerificationRequest err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeUpdateEmail)
|
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeUpdateEmail)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteVerificationRequest err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
verificationRequest, err = db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeMagicLinkLogin)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
err = db.Provider.DeleteVerificationRequest(ctx, verificationRequest)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteVerificationRequest err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
otp, err := db.Provider.GetOTPByEmail(ctx, email)
|
otp, err := db.Provider.GetOTPByEmail(ctx, email)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = db.Provider.DeleteOTP(ctx, otp)
|
err = db.Provider.DeleteOTP(ctx, otp)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteOTP err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbUser, err := db.Provider.GetUserByEmail(ctx, email)
|
dbUser, err := db.Provider.GetUserByEmail(ctx, email)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
db.Provider.DeleteUser(ctx, dbUser)
|
err = db.Provider.DeleteUser(ctx, dbUser)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("DeleteUser err", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,15 +17,12 @@ func updateAllUsersTest(t *testing.T, s TestSetup) {
|
|||||||
t.Helper()
|
t.Helper()
|
||||||
t.Run("Should update all users", func(t *testing.T) {
|
t.Run("Should update all users", func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
|
|
||||||
users := []models.User{}
|
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
user := models.User{
|
user := models.User{
|
||||||
Email: fmt.Sprintf("update_all_user_%d_%s", i, s.TestInfo.Email),
|
Email: fmt.Sprintf("update_all_user_%d_%s", i, s.TestInfo.Email),
|
||||||
SignupMethods: constants.AuthRecipeMethodBasicAuth,
|
SignupMethods: constants.AuthRecipeMethodBasicAuth,
|
||||||
Roles: "user",
|
Roles: "user",
|
||||||
}
|
}
|
||||||
users = append(users, user)
|
|
||||||
u, err := db.Provider.AddUser(ctx, user)
|
u, err := db.Provider.AddUser(ctx, user)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, u)
|
assert.NotNil(t, u)
|
||||||
@@ -56,12 +53,15 @@ func updateAllUsersTest(t *testing.T, s TestSetup) {
|
|||||||
Limit: 20,
|
Limit: 20,
|
||||||
Offset: 0,
|
Offset: 0,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, listUsers)
|
||||||
for _, u := range listUsers.Users {
|
for _, u := range listUsers.Users {
|
||||||
if utils.StringSliceContains(updateIds, u.ID) {
|
if utils.StringSliceContains(updateIds, u.ID) {
|
||||||
assert.False(t, refs.BoolValue(u.IsMultiFactorAuthEnabled))
|
assert.False(t, refs.BoolValue(u.IsMultiFactorAuthEnabled))
|
||||||
} else {
|
} else {
|
||||||
assert.True(t, refs.BoolValue(u.IsMultiFactorAuthEnabled))
|
assert.True(t, refs.BoolValue(u.IsMultiFactorAuthEnabled))
|
||||||
}
|
}
|
||||||
|
cleanData(u.Email)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -30,11 +30,13 @@ func updateProfileTests(t *testing.T, s TestSetup) {
|
|||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
|
||||||
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verificationRequest)
|
||||||
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
|
||||||
Token: verificationRequest.Token,
|
Token: verificationRequest.Token,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, verifyRes)
|
||||||
s.GinContext.Request.Header.Set("Authorization", "Bearer "+*verifyRes.AccessToken)
|
s.GinContext.Request.Header.Set("Authorization", "Bearer "+*verifyRes.AccessToken)
|
||||||
ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
|
ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
|
||||||
|
|
||||||
|
@@ -24,45 +24,73 @@ func updateWebhookTest(t *testing.T, s TestSetup) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
||||||
// get webhook
|
// get webhook
|
||||||
webhook, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent)
|
webhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, webhook)
|
assert.NotNil(t, webhooks)
|
||||||
|
assert.Equal(t, 2, len(webhooks))
|
||||||
|
for _, webhook := range webhooks {
|
||||||
// it should completely replace headers
|
// it should completely replace headers
|
||||||
webhook.Headers = map[string]interface{}{
|
webhook.Headers = map[string]interface{}{
|
||||||
"x-new-test": "test",
|
"x-new-test": "test",
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
res, err := resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
||||||
ID: webhook.ID,
|
ID: webhook.ID,
|
||||||
Headers: webhook.Headers,
|
Headers: webhook.Headers,
|
||||||
Enabled: refs.NewBoolRef(false),
|
Enabled: refs.NewBoolRef(false),
|
||||||
Endpoint: refs.NewStringRef("https://sometest.com"),
|
Endpoint: refs.NewStringRef("https://sometest.com"),
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, res)
|
assert.NotEmpty(t, res)
|
||||||
assert.NotEmpty(t, res.Message)
|
assert.NotEmpty(t, res.Message)
|
||||||
|
}
|
||||||
updatedWebhook, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent)
|
if len(webhooks) == 0 {
|
||||||
|
// avoid index out of range error
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Test updating webhook name
|
||||||
|
w := webhooks[0]
|
||||||
|
res, err := resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
||||||
|
ID: w.ID,
|
||||||
|
EventName: refs.NewStringRef(constants.UserAccessEnabledWebhookEvent),
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, updatedWebhook)
|
assert.NotNil(t, res)
|
||||||
assert.Equal(t, webhook.ID, updatedWebhook.ID)
|
// Check if webhooks with new name is as per expected len
|
||||||
assert.Equal(t, refs.StringValue(webhook.EventName), refs.StringValue(updatedWebhook.EventName))
|
accessWebhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserAccessEnabledWebhookEvent)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, 3, len(accessWebhooks))
|
||||||
|
// Revert name change
|
||||||
|
res, err = resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
||||||
|
ID: w.ID,
|
||||||
|
EventName: refs.NewStringRef(constants.UserDeletedWebhookEvent),
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, res)
|
||||||
|
updatedWebhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserDeletedWebhookEvent)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, updatedWebhooks)
|
||||||
|
assert.Equal(t, 2, len(updatedWebhooks))
|
||||||
|
for _, updatedWebhook := range updatedWebhooks {
|
||||||
|
assert.Contains(t, refs.StringValue(updatedWebhook.EventName), constants.UserDeletedWebhookEvent)
|
||||||
assert.Len(t, updatedWebhook.Headers, 1)
|
assert.Len(t, updatedWebhook.Headers, 1)
|
||||||
assert.False(t, refs.BoolValue(updatedWebhook.Enabled))
|
assert.False(t, refs.BoolValue(updatedWebhook.Enabled))
|
||||||
|
foundUpdatedHeader := false
|
||||||
for key, val := range updatedWebhook.Headers {
|
for key, val := range updatedWebhook.Headers {
|
||||||
assert.Equal(t, val, webhook.Headers[key])
|
if key == "x-new-test" && val == "test" {
|
||||||
|
foundUpdatedHeader = true
|
||||||
}
|
}
|
||||||
assert.Equal(t, refs.StringValue(updatedWebhook.Endpoint), "https://sometest.com")
|
}
|
||||||
|
assert.True(t, foundUpdatedHeader)
|
||||||
res, err = resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
assert.Equal(t, "https://sometest.com", refs.StringValue(updatedWebhook.Endpoint))
|
||||||
ID: webhook.ID,
|
res, err := resolvers.UpdateWebhookResolver(ctx, model.UpdateWebhookRequest{
|
||||||
Headers: webhook.Headers,
|
ID: updatedWebhook.ID,
|
||||||
|
Headers: updatedWebhook.Headers,
|
||||||
Enabled: refs.NewBoolRef(true),
|
Enabled: refs.NewBoolRef(true),
|
||||||
Endpoint: refs.NewStringRef(s.TestInfo.WebhookEndpoint),
|
Endpoint: refs.NewStringRef(s.TestInfo.WebhookEndpoint),
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, res)
|
assert.NotEmpty(t, res)
|
||||||
assert.NotEmpty(t, res.Message)
|
assert.NotEmpty(t, res.Message)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -34,7 +34,7 @@ func usersTest(t *testing.T, s TestSetup) {
|
|||||||
|
|
||||||
usersRes, err := resolvers.UsersResolver(ctx, pagination)
|
usersRes, err := resolvers.UsersResolver(ctx, pagination)
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
assert.Nil(t, usersRes)
|
||||||
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
h, err := crypto.EncryptPassword(adminSecret)
|
h, err := crypto.EncryptPassword(adminSecret)
|
||||||
|
@@ -53,6 +53,8 @@ func validateJwtTokenTest(t *testing.T, s TestSetup) {
|
|||||||
sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
|
sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
|
||||||
nonce := uuid.New().String()
|
nonce := uuid.New().String()
|
||||||
authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, "")
|
authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, "")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, authToken)
|
||||||
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
|
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
|
||||||
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
|
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
|
||||||
|
|
||||||
@@ -74,8 +76,8 @@ func validateJwtTokenTest(t *testing.T, s TestSetup) {
|
|||||||
Token: authToken.AccessToken.Token,
|
Token: authToken.AccessToken.Token,
|
||||||
Roles: []string{"invalid_role"},
|
Roles: []string{"invalid_role"},
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
assert.Nil(t, res)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run(`should validate the refresh token`, func(t *testing.T) {
|
t.Run(`should validate the refresh token`, func(t *testing.T) {
|
||||||
|
@@ -17,17 +17,14 @@ func verificationRequestsTest(t *testing.T, s TestSetup) {
|
|||||||
|
|
||||||
t.Run(`should get verification requests with admin secret only`, func(t *testing.T) {
|
t.Run(`should get verification requests with admin secret only`, func(t *testing.T) {
|
||||||
req, ctx := createContext(s)
|
req, ctx := createContext(s)
|
||||||
|
|
||||||
email := "verification_requests." + s.TestInfo.Email
|
email := "verification_requests." + s.TestInfo.Email
|
||||||
res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
res, err := resolvers.SignupResolver(ctx, model.SignUpInput{
|
||||||
Email: email,
|
Email: email,
|
||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, res)
|
assert.NotNil(t, res)
|
||||||
|
|
||||||
limit := int64(10)
|
limit := int64(10)
|
||||||
page := int64(1)
|
page := int64(1)
|
||||||
pagination := &model.PaginatedInput{
|
pagination := &model.PaginatedInput{
|
||||||
@@ -39,6 +36,7 @@ func verificationRequestsTest(t *testing.T, s TestSetup) {
|
|||||||
|
|
||||||
requests, err := resolvers.VerificationRequestsResolver(ctx, pagination)
|
requests, err := resolvers.VerificationRequestsResolver(ctx, pagination)
|
||||||
assert.NotNil(t, err, "unauthorized")
|
assert.NotNil(t, err, "unauthorized")
|
||||||
|
assert.Nil(t, requests)
|
||||||
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
adminSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
@@ -20,7 +20,8 @@ func verifyEmailTest(t *testing.T, s TestSetup) {
|
|||||||
Password: s.TestInfo.Password,
|
Password: s.TestInfo.Password,
|
||||||
ConfirmPassword: s.TestInfo.Password,
|
ConfirmPassword: s.TestInfo.Password,
|
||||||
})
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotNil(t, res)
|
||||||
user := *res.User
|
user := *res.User
|
||||||
assert.Equal(t, email, user.Email)
|
assert.Equal(t, email, user.Email)
|
||||||
assert.Nil(t, res.AccessToken, "access token should be nil")
|
assert.Nil(t, res.AccessToken, "access token should be nil")
|
||||||
|
@@ -29,17 +29,20 @@ func webhookLogsTest(t *testing.T, s TestSetup) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Greater(t, len(webhookLogs.WebhookLogs), 1)
|
assert.Greater(t, len(webhookLogs.WebhookLogs), 1)
|
||||||
|
|
||||||
webhooks, err := resolvers.WebhooksResolver(ctx, nil)
|
webhooks, err := resolvers.WebhooksResolver(ctx, &model.PaginatedInput{
|
||||||
|
Pagination: &model.PaginationInput{
|
||||||
|
Limit: refs.NewInt64Ref(20),
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, webhooks)
|
assert.NotEmpty(t, webhooks)
|
||||||
|
|
||||||
for _, w := range webhooks.Webhooks {
|
for _, w := range webhooks.Webhooks {
|
||||||
t.Run(fmt.Sprintf("should get webhook for webhook_id:%s", w.ID), func(t *testing.T) {
|
t.Run(fmt.Sprintf("should get webhook for webhook_id:%s", w.ID), func(t *testing.T) {
|
||||||
webhookLogs, err := resolvers.WebhookLogsResolver(ctx, &model.ListWebhookLogRequest{
|
webhookLogs, err := resolvers.WebhookLogsResolver(ctx, &model.ListWebhookLogRequest{
|
||||||
WebhookID: &w.ID,
|
WebhookID: &w.ID,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.GreaterOrEqual(t, len(webhookLogs.WebhookLogs), 1)
|
assert.GreaterOrEqual(t, len(webhookLogs.WebhookLogs), 1, refs.StringValue(w.EventName))
|
||||||
for _, wl := range webhookLogs.WebhookLogs {
|
for _, wl := range webhookLogs.WebhookLogs {
|
||||||
assert.Equal(t, refs.StringValue(wl.WebhookID), w.ID)
|
assert.Equal(t, refs.StringValue(wl.WebhookID), w.ID)
|
||||||
}
|
}
|
||||||
|
@@ -25,18 +25,20 @@ func webhookTest(t *testing.T, s TestSetup) {
|
|||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
||||||
|
|
||||||
// get webhook by event name
|
// get webhook by event name
|
||||||
webhook, err := db.Provider.GetWebhookByEventName(ctx, constants.UserCreatedWebhookEvent)
|
webhooks, err := db.Provider.GetWebhookByEventName(ctx, constants.UserCreatedWebhookEvent)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotNil(t, webhook)
|
assert.NotNil(t, webhooks)
|
||||||
|
assert.Equal(t, 2, len(webhooks))
|
||||||
|
for _, webhook := range webhooks {
|
||||||
res, err := resolvers.WebhookResolver(ctx, model.WebhookRequest{
|
res, err := resolvers.WebhookResolver(ctx, model.WebhookRequest{
|
||||||
ID: webhook.ID,
|
ID: webhook.ID,
|
||||||
})
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, res.ID, webhook.ID)
|
assert.Equal(t, res.ID, webhook.ID)
|
||||||
assert.Equal(t, refs.StringValue(res.Endpoint), refs.StringValue(webhook.Endpoint))
|
assert.Equal(t, refs.StringValue(res.Endpoint), refs.StringValue(webhook.Endpoint))
|
||||||
assert.Equal(t, refs.StringValue(res.EventName), refs.StringValue(webhook.EventName))
|
// assert.Equal(t, refs.StringValue(res.EventName), refs.StringValue(webhook.EventName))
|
||||||
assert.Equal(t, refs.BoolValue(res.Enabled), refs.BoolValue(webhook.Enabled))
|
assert.Equal(t, refs.BoolValue(res.Enabled), refs.BoolValue(webhook.Enabled))
|
||||||
assert.Len(t, res.Headers, len(webhook.Headers))
|
assert.Len(t, res.Headers, len(webhook.Headers))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,9 @@ import (
|
|||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/crypto"
|
"github.com/authorizerdev/authorizer/server/crypto"
|
||||||
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/memorystore"
|
"github.com/authorizerdev/authorizer/server/memorystore"
|
||||||
|
"github.com/authorizerdev/authorizer/server/refs"
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@@ -21,9 +23,13 @@ func webhooksTest(t *testing.T, s TestSetup) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
|
||||||
|
|
||||||
webhooks, err := resolvers.WebhooksResolver(ctx, nil)
|
webhooks, err := resolvers.WebhooksResolver(ctx, &model.PaginatedInput{
|
||||||
|
Pagination: &model.PaginationInput{
|
||||||
|
Limit: refs.NewInt64Ref(20),
|
||||||
|
},
|
||||||
|
})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, webhooks)
|
assert.NotEmpty(t, webhooks)
|
||||||
assert.Len(t, webhooks.Webhooks, len(s.TestInfo.TestWebhookEventTypes))
|
assert.Len(t, webhooks.Webhooks, len(s.TestInfo.TestWebhookEventTypes)*2)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -403,7 +403,6 @@ func CreateIDToken(user models.User, roles []string, hostname, nonce, atHash, cH
|
|||||||
"login_method": loginMethod,
|
"login_method": loginMethod,
|
||||||
claimKey: roles,
|
claimKey: roles,
|
||||||
}
|
}
|
||||||
|
|
||||||
// split nonce to see if its authorization code grant method
|
// split nonce to see if its authorization code grant method
|
||||||
if cHash != "" {
|
if cHash != "" {
|
||||||
customClaims["at_hash"] = atHash
|
customClaims["at_hash"] = atHash
|
||||||
|
@@ -17,29 +17,31 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func RegisterEvent(ctx context.Context, eventName string, authRecipe string, user models.User) error {
|
func RegisterEvent(ctx context.Context, eventName string, authRecipe string, user models.User) error {
|
||||||
webhook, err := db.Provider.GetWebhookByEventName(ctx, eventName)
|
webhooks, err := db.Provider.GetWebhookByEventName(ctx, eventName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Debug("Error getting webhook: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
for _, webhook := range webhooks {
|
||||||
if !refs.BoolValue(webhook.Enabled) {
|
if !refs.BoolValue(webhook.Enabled) {
|
||||||
return nil
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
userBytes, err := json.Marshal(user.AsAPIUser())
|
userBytes, err := json.Marshal(user.AsAPIUser())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error marshalling user obj: ", err)
|
log.Debug("error marshalling user obj: ", err)
|
||||||
return err
|
continue
|
||||||
}
|
}
|
||||||
userMap := map[string]interface{}{}
|
userMap := map[string]interface{}{}
|
||||||
err = json.Unmarshal(userBytes, &userMap)
|
err = json.Unmarshal(userBytes, &userMap)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error un-marshalling user obj: ", err)
|
log.Debug("error un-marshalling user obj: ", err)
|
||||||
return err
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
reqBody := map[string]interface{}{
|
reqBody := map[string]interface{}{
|
||||||
|
"webhook_id": webhook.ID,
|
||||||
"event_name": eventName,
|
"event_name": eventName,
|
||||||
|
"event_description": webhook.EventDescription,
|
||||||
"user": userMap,
|
"user": userMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,30 +52,32 @@ func RegisterEvent(ctx context.Context, eventName string, authRecipe string, use
|
|||||||
requestBody, err := json.Marshal(reqBody)
|
requestBody, err := json.Marshal(reqBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error marshalling requestBody obj: ", err)
|
log.Debug("error marshalling requestBody obj: ", err)
|
||||||
return err
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// dont trigger webhook call in case of test
|
// dont trigger webhook call in case of test
|
||||||
envKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEnv)
|
envKey, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyEnv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
continue
|
||||||
}
|
}
|
||||||
if envKey == constants.TestEnv {
|
if envKey == constants.TestEnv {
|
||||||
db.Provider.AddWebhookLog(ctx, models.WebhookLog{
|
_, err := db.Provider.AddWebhookLog(ctx, models.WebhookLog{
|
||||||
HttpStatus: 200,
|
HttpStatus: 200,
|
||||||
Request: string(requestBody),
|
Request: string(requestBody),
|
||||||
Response: string(`{"message": "test"}`),
|
Response: string(`{"message": "test"}`),
|
||||||
WebhookID: webhook.ID,
|
WebhookID: webhook.ID,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
return nil
|
log.Debug("error saving webhook log:", err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
requestBytesBuffer := bytes.NewBuffer(requestBody)
|
requestBytesBuffer := bytes.NewBuffer(requestBody)
|
||||||
req, err := http.NewRequest("POST", refs.StringValue(webhook.Endpoint), requestBytesBuffer)
|
req, err := http.NewRequest("POST", refs.StringValue(webhook.Endpoint), requestBytesBuffer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error creating webhook post request: ", err)
|
log.Debug("error creating webhook post request: ", err)
|
||||||
return err
|
continue
|
||||||
}
|
}
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
@@ -87,14 +91,14 @@ func RegisterEvent(ctx context.Context, eventName string, authRecipe string, use
|
|||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error making request: ", err)
|
log.Debug("error making request: ", err)
|
||||||
return err
|
continue
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
responseBytes, err := ioutil.ReadAll(resp.Body)
|
responseBytes, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("error reading response: ", err)
|
log.Debug("error reading response: ", err)
|
||||||
return err
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
statusCode := int64(resp.StatusCode)
|
statusCode := int64(resp.StatusCode)
|
||||||
@@ -104,11 +108,10 @@ func RegisterEvent(ctx context.Context, eventName string, authRecipe string, use
|
|||||||
Response: string(responseBytes),
|
Response: string(responseBytes),
|
||||||
WebhookID: webhook.ID,
|
WebhookID: webhook.ID,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("failed to add webhook log: ", err)
|
log.Debug("failed to add webhook log: ", err)
|
||||||
return err
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user