Compare commits

..

50 Commits

Author SHA1 Message Date
Lakhan Samani
7ced811e6e Merge pull request #399 from authorizerdev/feat/deativate-account
Add api to deactivate user account
2023-10-11 00:22:15 +05:30
Lakhan Samani
c1e1ee13f2 Add webhook event to fe 2023-10-11 00:21:58 +05:30
Lakhan Samani
60de61a74e fix webhook for deactiavtion 2023-10-11 00:20:15 +05:30
Lakhan Samani
843bc022fe Add api to deactivate user account 2023-10-11 00:16:53 +05:30
Lakhan Samani
ad41bcf792 Merge pull request #397 from VishwasShashidhar/main
Support macOS arm64 release binaries
2023-09-30 23:54:33 +05:30
Vishwas Shashidhar
ea2596b9ae support darwin-arm64 builds 2023-09-30 23:23:10 +05:30
Lakhan Samani
c8ccb89a67 Merge pull request #391 from team-scaletech/fix/webhook_bug_389
Fix/webhook bug 389
2023-09-13 17:46:55 +05:30
lemonScaletech
9519b53d4e Merge branch 'main' into fix/webhook_bug_389 2023-09-11 11:57:19 +05:30
Anand Kumar Panigrahi
e7cfaf4fbe Merge branch 'authorizerdev:main' into main 2023-09-11 11:55:27 +05:30
Lakhan Samani
0428488dab Merge pull request #393 from Juneezee/refactor/redundant-nil-check
refactor(server/utils): remove redundant nil check
2023-09-11 11:42:58 +05:30
Eng Zer Jun
f3b672a4cf refactor(server/utils): remove redundant nil check
From the Go specification:

  "3. If the map is nil, the number of iterations is 0." [1]

Therefore, an additional nil check for before the loop is unnecessary.

[1]: https://go.dev/ref/spec#For_range

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2023-09-09 12:57:20 +08:00
Lakhan Samani
1d6f569f92 fix: default value for disable playground 2023-09-09 07:11:13 +05:30
Lakhan Samani
fbdc24f314 Merge pull request #390 from team-scaletech/feat/disable_playground
feat: disable playground for non admin
2023-09-08 21:57:57 +05:30
Anand Kumar Panigrahi
1275644abe Merge branch 'authorizerdev:main' into main 2023-09-06 11:30:06 +05:30
Lakhan Samani
ac6b08c093 Merge pull request #392 from imchairmanm/feat/add_koyeb_button
Add button to deploy to Koyeb
2023-09-03 21:11:46 +05:30
Justin Ellingwood
fe461b675b Add button to deploy to Koyeb 2023-09-01 13:30:44 +01:00
lemonScaletech
77e219d990 fix:
* #389 resolved
* typo fixed
2023-08-29 18:14:48 +05:30
lemonScaletech
3ea13d7e93 refactor:
* added blank line eof .env.sample
2023-08-29 12:19:16 +05:30
lemonScaletech
940a09d172 Merge remote-tracking branch 'origin/feat/disable_playground' into feat/disable_playground
# Conflicts:
#	app/yarn.lock
#	server/constants/env.go
#	server/env/env.go
#	server/env/persist_env.go
#	server/memorystore/providers/redis/store.go
2023-08-29 12:00:24 +05:30
lemonScaletech
3ac6875f87 feat:
* resolved conflicts
2023-08-29 11:55:27 +05:30
lemonScaletech
937506ff64 Merge branch 'main' into feat/disable_playground
# Conflicts:
#	app/yarn.lock
#	dashboard/yarn.lock
#	server/constants/env.go
#	server/env/env.go
#	server/env/persist_env.go
#	server/graph/model/models_gen.go
#	server/memorystore/providers/redis/store.go
2023-08-29 11:44:07 +05:30
lemonScaletech
9795ba9097 feat:
* added disable playground functionality
 * added toggle button for playground in dashboard
2023-08-29 11:36:18 +05:30
vipul patel
11dbe9d97a Merge pull request #1 from authorizerdev/main
Authorizer to foke authorizer
2023-08-29 09:15:53 +05:30
lemonScaletech
c9b8bbc3e1 feat:
* added disable playground functionality
 * added toggle button for playground in dashboard
2023-08-28 19:51:42 +05:30
Lakhan Samani
a124edfaee Add user to validate_session
Resolves #379
2023-08-19 20:45:20 +05:30
Lakhan Samani
5e6b033024 fix microsoft active directory config 2023-08-17 14:20:31 +05:30
Lakhan Samani
171d4e3fff remove unused code 2023-08-14 14:16:54 +05:30
Lakhan Samani
cf96a0087f Fix tests for verifying otp using mfa session 2023-08-14 14:15:52 +05:30
Lakhan Samani
09cfad9c27 Merge pull request #382 from authorizerdev/feat-add-field-for-app-data
Add app_data
2023-08-14 12:05:58 +05:30
Lakhan Samani
35e563ab3b Add app_data 2023-08-14 12:01:37 +05:30
Lakhan Samani
e625ed9633 allow common tenant for microsoft 2023-08-03 14:43:27 +05:30
Lakhan Samani
a042c202a0 fix microsoft active directory config 2023-08-03 13:29:07 +05:30
Lakhan Samani
7a76b783b1 Merge pull request #372 from catusax/main
feat: add mfa session to secure otp login
2023-08-03 12:34:39 +05:30
Lakhan Samani
e5400bc7bd fix microsoft active directory config 2023-08-03 12:33:20 +05:30
Lakhan Samani
a8503666e3 fix: add events for signup 2023-08-02 10:02:41 +05:30
Lakhan Samani
b028be3cbc Merge pull request #377 from authorizerdev/fix-webhook-test-endpoint
fix: test webhook endpoint mutation
2023-08-02 00:04:55 +05:30
Lakhan Samani
9a8d20b698 fix: test webhook endpoint mutation
Resolves #376
2023-08-02 00:04:07 +05:30
Lakhan Samani
fab3c2f87e Merge pull request #375 from authorizerdev/fix-db-refs
Fix db refs
2023-08-01 23:38:00 +05:30
catusax
0c334856bc Merge branch 'main' into main 2023-07-24 14:04:26 +08:00
catusax
ba0cf189de userid ass mfa session key 2023-07-24 12:00:30 +08:00
Lakhan Samani
9f52c08883 [app] bump authorizer-react 1.1.13 2023-07-24 11:56:56 +08:00
Lakhan Samani
80f3698f06 [app] bump authorizer-react 1.1.12 2023-07-24 11:56:56 +08:00
Lakhan Samani
2a2b7abc08 Add optional show_mobile_otp_screen 2023-07-24 11:56:56 +08:00
Lakhan Samani
27e3ed82e4 Update resend otp 2023-07-24 11:56:55 +08:00
Lakhan Samani
6077702626 fix: tests for otp refactor 2023-07-24 11:56:55 +08:00
Lakhan Samani
cf54fcef03 Fix tests 2023-07-24 11:56:55 +08:00
Lakhan Samani
2f849b8f0c Refactor code for otp 2023-07-24 11:56:55 +08:00
Lakhan Samani
85ca0f09bf [draft] Move sms verificaiton to otp models 2023-07-24 11:55:26 +08:00
catusax
e7652db89c add comments 2023-07-23 13:02:14 +08:00
catusax
5018462559 feat: add mfa session to secure otp login 2023-07-20 15:11:39 +08:00
58 changed files with 2464 additions and 1594 deletions

View File

@@ -1,4 +1,5 @@
ENV=production ENV=production
DATABASE_URL=data.db DATABASE_URL=data.db
DATABASE_TYPE=sqlite DATABASE_TYPE=sqlite
CUSTOM_ACCESS_TOKEN_SCRIPT="function(user,tokenPayload){var data = tokenPayload;data.extra = {'x-extra-id': user.id};return data;}" CUSTOM_ACCESS_TOKEN_SCRIPT="function(user,tokenPayload){var data = tokenPayload;data.extra = {'x-extra-id': user.id};return data;}"
DISABLE_PLAYGROUND=true

View File

@@ -62,12 +62,14 @@ jobs:
run: | run: |
make clean && \ make clean && \
make build && \ make build && \
mkdir -p authorizer-${VERSION}-darwin-arm64/build authorizer-${VERSION}-darwin-arm64/app authorizer-${VERSION}-darwin-arm64/dashboard && cp build/darwin/arm64/server authorizer-${VERSION}-darwin-arm64/build/ && cp .env authorizer-${VERSION}-darwin-arm64/.env && cp -rf app/build authorizer-${VERSION}-darwin-arm64/app/build && cp -rf templates authorizer-${VERSION}-darwin-arm64/ && cp -rf dashboard/build authorizer-${VERSION}-darwin-arm64/dashboard/build && tar cvfz authorizer-${VERSION}-darwin-arm64.tar.gz authorizer-${VERSION}-darwin-arm64 && \
mkdir -p authorizer-${VERSION}-darwin-amd64/build authorizer-${VERSION}-darwin-amd64/app authorizer-${VERSION}-darwin-amd64/dashboard && cp build/darwin/amd64/server authorizer-${VERSION}-darwin-amd64/build/ && cp .env authorizer-${VERSION}-darwin-amd64/.env && cp -rf app/build authorizer-${VERSION}-darwin-amd64/app/build && cp -rf templates authorizer-${VERSION}-darwin-amd64/ && cp -rf dashboard/build authorizer-${VERSION}-darwin-amd64/dashboard/build && tar cvfz authorizer-${VERSION}-darwin-amd64.tar.gz authorizer-${VERSION}-darwin-amd64 && \ mkdir -p authorizer-${VERSION}-darwin-amd64/build authorizer-${VERSION}-darwin-amd64/app authorizer-${VERSION}-darwin-amd64/dashboard && cp build/darwin/amd64/server authorizer-${VERSION}-darwin-amd64/build/ && cp .env authorizer-${VERSION}-darwin-amd64/.env && cp -rf app/build authorizer-${VERSION}-darwin-amd64/app/build && cp -rf templates authorizer-${VERSION}-darwin-amd64/ && cp -rf dashboard/build authorizer-${VERSION}-darwin-amd64/dashboard/build && tar cvfz authorizer-${VERSION}-darwin-amd64.tar.gz authorizer-${VERSION}-darwin-amd64 && \
mkdir -p authorizer-${VERSION}-linux-amd64/build authorizer-${VERSION}-linux-amd64/app authorizer-${VERSION}-linux-amd64/dashboard && cp build/linux/amd64/server authorizer-${VERSION}-linux-amd64/build/ && cp .env authorizer-${VERSION}-linux-amd64/.env && cp -rf app/build authorizer-${VERSION}-linux-amd64/app/build && cp -rf templates authorizer-${VERSION}-linux-amd64/ && cp -rf dashboard/build authorizer-${VERSION}-linux-amd64/dashboard/build && tar cvfz authorizer-${VERSION}-linux-amd64.tar.gz authorizer-${VERSION}-linux-amd64 && \ mkdir -p authorizer-${VERSION}-linux-amd64/build authorizer-${VERSION}-linux-amd64/app authorizer-${VERSION}-linux-amd64/dashboard && cp build/linux/amd64/server authorizer-${VERSION}-linux-amd64/build/ && cp .env authorizer-${VERSION}-linux-amd64/.env && cp -rf app/build authorizer-${VERSION}-linux-amd64/app/build && cp -rf templates authorizer-${VERSION}-linux-amd64/ && cp -rf dashboard/build authorizer-${VERSION}-linux-amd64/dashboard/build && tar cvfz authorizer-${VERSION}-linux-amd64.tar.gz authorizer-${VERSION}-linux-amd64 && \
mkdir -p authorizer-${VERSION}-linux-arm64/build authorizer-${VERSION}-linux-arm64/app authorizer-${VERSION}-linux-arm64/dashboard && cp build/linux/arm64/server authorizer-${VERSION}-linux-arm64/build/ && cp .env authorizer-${VERSION}-linux-arm64/.env && cp -rf app/build authorizer-${VERSION}-linux-arm64/app/build && cp -rf templates authorizer-${VERSION}-linux-arm64/ && cp -rf dashboard/build authorizer-${VERSION}-linux-arm64/dashboard/build && tar cvfz authorizer-${VERSION}-linux-arm64.tar.gz authorizer-${VERSION}-linux-arm64 && \ mkdir -p authorizer-${VERSION}-linux-arm64/build authorizer-${VERSION}-linux-arm64/app authorizer-${VERSION}-linux-arm64/dashboard && cp build/linux/arm64/server authorizer-${VERSION}-linux-arm64/build/ && cp .env authorizer-${VERSION}-linux-arm64/.env && cp -rf app/build authorizer-${VERSION}-linux-arm64/app/build && cp -rf templates authorizer-${VERSION}-linux-arm64/ && cp -rf dashboard/build authorizer-${VERSION}-linux-arm64/dashboard/build && tar cvfz authorizer-${VERSION}-linux-arm64.tar.gz authorizer-${VERSION}-linux-arm64 && \
mkdir -p authorizer-${VERSION}-windows-amd64/build authorizer-${VERSION}-windows-amd64/app authorizer-${VERSION}-windows-amd64/dashboard && cp build/windows/amd64/server.exe authorizer-${VERSION}-windows-amd64/build/ && cp .env authorizer-${VERSION}-windows-amd64/.env && cp -rf app/build authorizer-${VERSION}-windows-amd64/app/build && cp -rf templates authorizer-${VERSION}-windows-amd64/ && cp -rf dashboard/build authorizer-${VERSION}-windows-amd64/dashboard/build && zip -vr authorizer-${VERSION}-windows-amd64.zip authorizer-${VERSION}-windows-amd64 mkdir -p authorizer-${VERSION}-windows-amd64/build authorizer-${VERSION}-windows-amd64/app authorizer-${VERSION}-windows-amd64/dashboard && cp build/windows/amd64/server.exe authorizer-${VERSION}-windows-amd64/build/ && cp .env authorizer-${VERSION}-windows-amd64/.env && cp -rf app/build authorizer-${VERSION}-windows-amd64/app/build && cp -rf templates authorizer-${VERSION}-windows-amd64/ && cp -rf dashboard/build authorizer-${VERSION}-windows-amd64/dashboard/build && zip -vr authorizer-${VERSION}-windows-amd64.zip authorizer-${VERSION}-windows-amd64
- name: Upload assets - name: Upload assets
run: | run: |
github-assets-uploader -f authorizer-${VERSION}-darwin-arm64.tar.gz -mediatype application/gzip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION}
github-assets-uploader -f authorizer-${VERSION}-darwin-amd64.tar.gz -mediatype application/gzip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION} github-assets-uploader -f authorizer-${VERSION}-darwin-amd64.tar.gz -mediatype application/gzip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION}
github-assets-uploader -f authorizer-${VERSION}-linux-amd64.tar.gz -mediatype application/gzip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION} github-assets-uploader -f authorizer-${VERSION}-linux-amd64.tar.gz -mediatype application/gzip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION}
github-assets-uploader -f authorizer-${VERSION}-linux-arm64.tar.gz -mediatype application/gzip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION} github-assets-uploader -f authorizer-${VERSION}-linux-arm64.tar.gz -mediatype application/gzip -repo authorizerdev/authorizer -token ${{secrets.RELEASE_TOKEN}} -tag ${VERSION}

3
.gitignore vendored
View File

@@ -17,4 +17,5 @@ test.db
yalc.lock yalc.lock
certs/ certs/
*-shm *-shm
*-wal *-wal
.idea

View File

@@ -1,4 +1,4 @@
FROM golang:1.19.5-alpine as go-builder FROM golang:1.21.1-alpine as go-builder
WORKDIR /authorizer WORKDIR /authorizer
COPY server server COPY server server
COPY Makefile . COPY Makefile .

View File

@@ -5,7 +5,7 @@ cmd:
cd server && go build -ldflags "-w -X main.VERSION=$(VERSION)" -o '../build/server' cd server && go build -ldflags "-w -X main.VERSION=$(VERSION)" -o '../build/server'
build: build:
cd server && gox \ cd server && gox \
-osarch="linux/amd64 linux/arm64 darwin/amd64 windows/amd64" \ -osarch="linux/amd64 linux/arm64 darwin/arm64 darwin/amd64 windows/amd64" \
-ldflags "-w -X main.VERSION=$(VERSION)" \ -ldflags "-w -X main.VERSION=$(VERSION)" \
-output="../build/{{.OS}}/{{.Arch}}/server" \ -output="../build/{{.OS}}/{{.Arch}}/server" \
./... ./...
@@ -30,7 +30,7 @@ test-arangodb:
cd server && go clean --testcache && TEST_DBS="arangodb" go test -p 1 -v ./test cd server && go clean --testcache && TEST_DBS="arangodb" go test -p 1 -v ./test
docker rm -vf authorizer_arangodb docker rm -vf authorizer_arangodb
test-dynamodb: test-dynamodb:
docker run -d --name dynamodb-local-test -p 8000:8000 amazon/dynamodb-local:latest docker run -d --name dynamodb-local-test -p 8000:8000 amazon/dynamodb-local:latest
cd server && go clean --testcache && TEST_DBS="dynamodb" go test -p 1 -v ./test cd server && go clean --testcache && TEST_DBS="dynamodb" go test -p 1 -v ./test
docker rm -vf dynamodb-local-test docker rm -vf dynamodb-local-test
test-couchbase: test-couchbase:
@@ -56,4 +56,4 @@ generate-graphql:
cd server && go run github.com/99designs/gqlgen generate && go mod tidy cd server && go run github.com/99designs/gqlgen generate && go mod tidy
generate-db-template: generate-db-template:
cp -rf server/db/providers/provider_template server/db/providers/${dbname} cp -rf server/db/providers/provider_template server/db/providers/${dbname}
find server/db/providers/${dbname} -type f -exec sed -i -e 's/provider_template/${dbname}/g' {} \; find server/db/providers/${dbname} -type f -exec sed -i -e 's/provider_template/${dbname}/g' {} \;

View File

@@ -68,6 +68,7 @@ Deploy production ready Authorizer instance using one click deployment options a
| Railway.app | <a href="https://railway.app/new/template/nwXp1C?referralCode=FEF4uT"><img src="https://railway.app/button.svg" style="height: 44px" alt="Deploy on Railway"></a> | [docs](https://docs.authorizer.dev/deployment/railway) | | Railway.app | <a href="https://railway.app/new/template/nwXp1C?referralCode=FEF4uT"><img src="https://railway.app/button.svg" style="height: 44px" alt="Deploy on Railway"></a> | [docs](https://docs.authorizer.dev/deployment/railway) |
| Heroku | <a href="https://heroku.com/deploy?template=https://github.com/authorizerdev/authorizer-heroku"><img src="https://www.herokucdn.com/deploy/button.svg" alt="Deploy to Heroku" style="height: 44px;"></a> | [docs](https://docs.authorizer.dev/deployment/heroku) | | Heroku | <a href="https://heroku.com/deploy?template=https://github.com/authorizerdev/authorizer-heroku"><img src="https://www.herokucdn.com/deploy/button.svg" alt="Deploy to Heroku" style="height: 44px;"></a> | [docs](https://docs.authorizer.dev/deployment/heroku) |
| Render | [![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/authorizerdev/authorizer-render) | [docs](https://docs.authorizer.dev/deployment/render) | | Render | [![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/authorizerdev/authorizer-render) | [docs](https://docs.authorizer.dev/deployment/render) |
| Koyeb | <a target="_blank" href="https://app.koyeb.com/deploy?name=authorizer&type=docker&image=docker.io/lakhansamani/authorizer&env[PORT]=8000&env[DATABASE_TYPE]=postgres&env[DATABASE_URL]=CHANGE_ME&ports=8000;http;/"><img alt="Deploy to Koyeb" src="https://www.koyeb.com/static/images/deploy/button.svg" /></a> | [docs](https://docs.authorizer.dev/deployment/koyeb) |
### Deploy Authorizer Using Source Code ### Deploy Authorizer Using Source Code

View File

@@ -3,125 +3,125 @@
"@authorizerdev/authorizer-js@^1.2.6": "@authorizerdev/authorizer-js@^1.2.6":
"integrity" "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==" version "1.2.6"
"resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz" resolved "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz"
"version" "1.2.6" integrity sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==
dependencies: dependencies:
"cross-fetch" "^3.1.5" cross-fetch "^3.1.5"
"@authorizerdev/authorizer-react@^1.1.13": "@authorizerdev/authorizer-react@^1.1.13":
"integrity" "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==" version "1.1.13"
"resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz" resolved "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz"
"version" "1.1.13" integrity sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==
dependencies: dependencies:
"@authorizerdev/authorizer-js" "^1.2.6" "@authorizerdev/authorizer-js" "^1.2.6"
"@babel/code-frame@^7.16.7": "@babel/code-frame@^7.16.7":
"integrity" "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==" version "7.16.7"
"resolved" "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz"
"version" "7.16.7" integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==
dependencies: dependencies:
"@babel/highlight" "^7.16.7" "@babel/highlight" "^7.16.7"
"@babel/generator@^7.16.8": "@babel/generator@^7.16.8":
"integrity" "sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==" version "7.16.8"
"resolved" "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz" resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz"
"version" "7.16.8" integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw==
dependencies: dependencies:
"@babel/types" "^7.16.8" "@babel/types" "^7.16.8"
"jsesc" "^2.5.1" jsesc "^2.5.1"
"source-map" "^0.5.0" source-map "^0.5.0"
"@babel/helper-annotate-as-pure@^7.16.0": "@babel/helper-annotate-as-pure@^7.16.0":
"integrity" "sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==" version "7.16.7"
"resolved" "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz" resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz"
"version" "7.16.7" integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw==
dependencies: dependencies:
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/helper-environment-visitor@^7.16.7": "@babel/helper-environment-visitor@^7.16.7":
"integrity" "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==" version "7.16.7"
"resolved" "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz" resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz"
"version" "7.16.7" integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==
dependencies: dependencies:
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/helper-function-name@^7.16.7": "@babel/helper-function-name@^7.16.7":
"integrity" "sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==" version "7.16.7"
"resolved" "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz" resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz"
"version" "7.16.7" integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==
dependencies: dependencies:
"@babel/helper-get-function-arity" "^7.16.7" "@babel/helper-get-function-arity" "^7.16.7"
"@babel/template" "^7.16.7" "@babel/template" "^7.16.7"
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/helper-get-function-arity@^7.16.7": "@babel/helper-get-function-arity@^7.16.7":
"integrity" "sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==" version "7.16.7"
"resolved" "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz" resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz"
"version" "7.16.7" integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==
dependencies: dependencies:
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/helper-hoist-variables@^7.16.7": "@babel/helper-hoist-variables@^7.16.7":
"integrity" "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==" version "7.16.7"
"resolved" "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz" resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz"
"version" "7.16.7" integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==
dependencies: dependencies:
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.16.0": "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.16.0":
"integrity" "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==" version "7.16.7"
"resolved" "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz" resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz"
"version" "7.16.7" integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==
dependencies: dependencies:
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/helper-split-export-declaration@^7.16.7": "@babel/helper-split-export-declaration@^7.16.7":
"integrity" "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==" version "7.16.7"
"resolved" "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz" resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz"
"version" "7.16.7" integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==
dependencies: dependencies:
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/helper-validator-identifier@^7.16.7": "@babel/helper-validator-identifier@^7.16.7":
"integrity" "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==" version "7.16.7"
"resolved" "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz"
"version" "7.16.7" integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
"@babel/highlight@^7.16.7": "@babel/highlight@^7.16.7":
"integrity" "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==" version "7.16.10"
"resolved" "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz" resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz"
"version" "7.16.10" integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==
dependencies: dependencies:
"@babel/helper-validator-identifier" "^7.16.7" "@babel/helper-validator-identifier" "^7.16.7"
"chalk" "^2.0.0" chalk "^2.0.0"
"js-tokens" "^4.0.0" js-tokens "^4.0.0"
"@babel/parser@^7.16.10", "@babel/parser@^7.16.7": "@babel/parser@^7.16.10", "@babel/parser@^7.16.7":
"integrity" "sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==" version "7.16.12"
"resolved" "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz" resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.16.12.tgz"
"version" "7.16.12" integrity sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==
"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1": "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1":
"integrity" "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==" version "7.14.8"
"resolved" "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz"
"version" "7.14.8" integrity sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==
dependencies: dependencies:
"regenerator-runtime" "^0.13.4" regenerator-runtime "^0.13.4"
"@babel/template@^7.16.7": "@babel/template@^7.16.7":
"integrity" "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==" version "7.16.7"
"resolved" "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz" resolved "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz"
"version" "7.16.7" integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==
dependencies: dependencies:
"@babel/code-frame" "^7.16.7" "@babel/code-frame" "^7.16.7"
"@babel/parser" "^7.16.7" "@babel/parser" "^7.16.7"
"@babel/types" "^7.16.7" "@babel/types" "^7.16.7"
"@babel/traverse@^7.4.5": "@babel/traverse@^7.4.5":
"integrity" "sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==" version "7.16.10"
"resolved" "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz" resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz"
"version" "7.16.10" integrity sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw==
dependencies: dependencies:
"@babel/code-frame" "^7.16.7" "@babel/code-frame" "^7.16.7"
"@babel/generator" "^7.16.8" "@babel/generator" "^7.16.8"
@@ -131,458 +131,458 @@
"@babel/helper-split-export-declaration" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7"
"@babel/parser" "^7.16.10" "@babel/parser" "^7.16.10"
"@babel/types" "^7.16.8" "@babel/types" "^7.16.8"
"debug" "^4.1.0" debug "^4.1.0"
"globals" "^11.1.0" globals "^11.1.0"
"@babel/types@^7.16.7", "@babel/types@^7.16.8": "@babel/types@^7.16.7", "@babel/types@^7.16.8":
"integrity" "sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==" version "7.16.8"
"resolved" "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz" resolved "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz"
"version" "7.16.8" integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg==
dependencies: dependencies:
"@babel/helper-validator-identifier" "^7.16.7" "@babel/helper-validator-identifier" "^7.16.7"
"to-fast-properties" "^2.0.0" to-fast-properties "^2.0.0"
"@emotion/is-prop-valid@^0.8.8": "@emotion/is-prop-valid@^0.8.8":
"integrity" "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==" version "0.8.8"
"resolved" "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz" resolved "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz"
"version" "0.8.8" integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==
dependencies: dependencies:
"@emotion/memoize" "0.7.4" "@emotion/memoize" "0.7.4"
"@emotion/memoize@0.7.4": "@emotion/memoize@0.7.4":
"integrity" "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" version "0.7.4"
"resolved" "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz" resolved "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz"
"version" "0.7.4" integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
"@emotion/stylis@^0.8.4": "@emotion/stylis@^0.8.4":
"integrity" "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" version "0.8.5"
"resolved" "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz" resolved "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz"
"version" "0.8.5" integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
"@emotion/unitless@^0.7.4": "@emotion/unitless@^0.7.4":
"integrity" "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" version "0.7.5"
"resolved" "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz" resolved "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz"
"version" "0.7.5" integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
"@types/history@*": "@types/history@*":
"integrity" "sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==" version "4.7.9"
"resolved" "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz" resolved "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz"
"version" "4.7.9" integrity sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==
"@types/hoist-non-react-statics@*": "@types/hoist-non-react-statics@*":
"integrity" "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==" version "3.3.1"
"resolved" "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz" resolved "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz"
"version" "3.3.1" integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"hoist-non-react-statics" "^3.3.0" hoist-non-react-statics "^3.3.0"
"@types/prop-types@*": "@types/prop-types@*":
"integrity" "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==" version "15.7.4"
"resolved" "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz" resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz"
"version" "15.7.4" integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
"@types/react-dom@^17.0.9": "@types/react-dom@^17.0.9":
"integrity" "sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==" version "17.0.9"
"resolved" "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz" resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.9.tgz"
"version" "17.0.9" integrity sha512-wIvGxLfgpVDSAMH5utdL9Ngm5Owu0VsGmldro3ORLXV8CShrL8awVj06NuEXFQ5xyaYfdca7Sgbk/50Ri1GdPg==
dependencies: dependencies:
"@types/react" "*" "@types/react" "*"
"@types/react-router-dom@^5.1.8": "@types/react-router-dom@^5.1.8":
"integrity" "sha512-03xHyncBzG0PmDmf8pf3rehtjY0NpUj7TIN46FrT5n1ZWHPZvXz32gUyNboJ+xsL8cpg8bQVLcllptcQHvocrw==" version "5.1.8"
"resolved" "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.8.tgz" resolved "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.8.tgz"
"version" "5.1.8" integrity sha512-03xHyncBzG0PmDmf8pf3rehtjY0NpUj7TIN46FrT5n1ZWHPZvXz32gUyNboJ+xsL8cpg8bQVLcllptcQHvocrw==
dependencies: dependencies:
"@types/history" "*" "@types/history" "*"
"@types/react" "*" "@types/react" "*"
"@types/react-router" "*" "@types/react-router" "*"
"@types/react-router@*": "@types/react-router@*":
"integrity" "sha512-8d7nR/fNSqlTFGHti0R3F9WwIertOaaA1UEB8/jr5l5mDMOs4CidEgvvYMw4ivqrBK+vtVLxyTj2P+Pr/dtgzg==" version "5.1.16"
"resolved" "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.16.tgz" resolved "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.16.tgz"
"version" "5.1.16" integrity sha512-8d7nR/fNSqlTFGHti0R3F9WwIertOaaA1UEB8/jr5l5mDMOs4CidEgvvYMw4ivqrBK+vtVLxyTj2P+Pr/dtgzg==
dependencies: dependencies:
"@types/history" "*" "@types/history" "*"
"@types/react" "*" "@types/react" "*"
"@types/react@*", "@types/react@^17.0.15": "@types/react@*", "@types/react@^17.0.15":
"integrity" "sha512-uTKHDK9STXFHLaKv6IMnwp52fm0hwU+N89w/p9grdUqcFA6WuqDyPhaWopbNyE1k/VhgzmHl8pu1L4wITtmlLw==" version "17.0.15"
"resolved" "https://registry.npmjs.org/@types/react/-/react-17.0.15.tgz" resolved "https://registry.npmjs.org/@types/react/-/react-17.0.15.tgz"
"version" "17.0.15" integrity sha512-uTKHDK9STXFHLaKv6IMnwp52fm0hwU+N89w/p9grdUqcFA6WuqDyPhaWopbNyE1k/VhgzmHl8pu1L4wITtmlLw==
dependencies: dependencies:
"@types/prop-types" "*" "@types/prop-types" "*"
"@types/scheduler" "*" "@types/scheduler" "*"
"csstype" "^3.0.2" csstype "^3.0.2"
"@types/scheduler@*": "@types/scheduler@*":
"integrity" "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" version "0.16.2"
"resolved" "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz" resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz"
"version" "0.16.2" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
"@types/styled-components@^5.1.11": "@types/styled-components@^5.1.11":
"integrity" "sha512-fgwl+0Pa8pdkwXRoVPP9JbqF0Ivo9llnmsm+7TCI330kbPIFd9qv1Lrhr37shf4tnxCOSu+/IgqM7uJXLWZZNQ==" version "5.1.25"
"resolved" "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.25.tgz" resolved "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.25.tgz"
"version" "5.1.25" integrity sha512-fgwl+0Pa8pdkwXRoVPP9JbqF0Ivo9llnmsm+7TCI330kbPIFd9qv1Lrhr37shf4tnxCOSu+/IgqM7uJXLWZZNQ==
dependencies: dependencies:
"@types/hoist-non-react-statics" "*" "@types/hoist-non-react-statics" "*"
"@types/react" "*" "@types/react" "*"
"csstype" "^3.0.2" csstype "^3.0.2"
"ansi-styles@^3.2.1": ansi-styles@^3.2.1:
"integrity" "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==" version "3.2.1"
"resolved" "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
"version" "3.2.1" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
dependencies: dependencies:
"color-convert" "^1.9.0" color-convert "^1.9.0"
"babel-plugin-styled-components@>= 1.12.0": "babel-plugin-styled-components@>= 1.12.0":
"integrity" "sha512-7eG5NE8rChnNTDxa6LQfynwgHTVOYYaHJbUYSlOhk8QBXIQiMBKq4gyfHBBKPrxUcVBXVJL61ihduCpCQbuNbw==" version "2.0.2"
"resolved" "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.2.tgz" resolved "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.2.tgz"
"version" "2.0.2" integrity sha512-7eG5NE8rChnNTDxa6LQfynwgHTVOYYaHJbUYSlOhk8QBXIQiMBKq4gyfHBBKPrxUcVBXVJL61ihduCpCQbuNbw==
dependencies: dependencies:
"@babel/helper-annotate-as-pure" "^7.16.0" "@babel/helper-annotate-as-pure" "^7.16.0"
"@babel/helper-module-imports" "^7.16.0" "@babel/helper-module-imports" "^7.16.0"
"babel-plugin-syntax-jsx" "^6.18.0" babel-plugin-syntax-jsx "^6.18.0"
"lodash" "^4.17.11" lodash "^4.17.11"
"babel-plugin-syntax-jsx@^6.18.0": babel-plugin-syntax-jsx@^6.18.0:
"integrity" "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" version "6.18.0"
"resolved" "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz" resolved "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz"
"version" "6.18.0" integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=
"camelize@^1.0.0": camelize@^1.0.0:
"integrity" "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" version "1.0.0"
"resolved" "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz" resolved "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz"
"version" "1.0.0" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=
"chalk@^2.0.0": chalk@^2.0.0:
"integrity" "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==" version "2.4.2"
"resolved" "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
"version" "2.4.2" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies: dependencies:
"ansi-styles" "^3.2.1" ansi-styles "^3.2.1"
"escape-string-regexp" "^1.0.5" escape-string-regexp "^1.0.5"
"supports-color" "^5.3.0" supports-color "^5.3.0"
"color-convert@^1.9.0": color-convert@^1.9.0:
"integrity" "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==" version "1.9.3"
"resolved" "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
"version" "1.9.3" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
dependencies: dependencies:
"color-name" "1.1.3" color-name "1.1.3"
"color-name@1.1.3": color-name@1.1.3:
"integrity" "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" version "1.1.3"
"resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
"version" "1.1.3" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
"cross-fetch@^3.1.5": cross-fetch@^3.1.5:
"integrity" "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==" version "3.1.8"
"resolved" "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz" resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz"
"version" "3.1.8" integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==
dependencies: dependencies:
"node-fetch" "^2.6.12" node-fetch "^2.6.12"
"css-color-keywords@^1.0.0": css-color-keywords@^1.0.0:
"integrity" "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" version "1.0.0"
"resolved" "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz" resolved "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz"
"version" "1.0.0" integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=
"css-to-react-native@^3.0.0": css-to-react-native@^3.0.0:
"integrity" "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==" version "3.0.0"
"resolved" "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz" resolved "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz"
"version" "3.0.0" integrity sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==
dependencies: dependencies:
"camelize" "^1.0.0" camelize "^1.0.0"
"css-color-keywords" "^1.0.0" css-color-keywords "^1.0.0"
"postcss-value-parser" "^4.0.2" postcss-value-parser "^4.0.2"
"csstype@^3.0.2": csstype@^3.0.2:
"integrity" "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" version "3.0.8"
"resolved" "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz" resolved "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz"
"version" "3.0.8" integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
"debug@^4.1.0": debug@^4.1.0:
"integrity" "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==" version "4.3.3"
"resolved" "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz" resolved "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz"
"version" "4.3.3" integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
dependencies: dependencies:
"ms" "2.1.2" ms "2.1.2"
"esbuild@^0.12.17": esbuild@^0.12.17:
"integrity" "sha512-GshKJyVYUnlSXIZj/NheC2O0Kblh42CS7P1wJyTbbIHevTG4jYMS9NNw8EOd8dDWD0dzydYHS01MpZoUcQXB4g==" version "0.12.17"
"resolved" "https://registry.npmjs.org/esbuild/-/esbuild-0.12.17.tgz" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.12.17.tgz"
"version" "0.12.17" integrity sha512-GshKJyVYUnlSXIZj/NheC2O0Kblh42CS7P1wJyTbbIHevTG4jYMS9NNw8EOd8dDWD0dzydYHS01MpZoUcQXB4g==
"escape-string-regexp@^1.0.5": escape-string-regexp@^1.0.5:
"integrity" "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" version "1.0.5"
"resolved" "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz"
"version" "1.0.5" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
"globals@^11.1.0": globals@^11.1.0:
"integrity" "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" version "11.12.0"
"resolved" "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz"
"version" "11.12.0" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
"has-flag@^3.0.0": has-flag@^3.0.0:
"integrity" "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" version "3.0.0"
"resolved" "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz"
"version" "3.0.0" integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
"history@^4.9.0": history@^4.9.0:
"integrity" "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==" version "4.10.1"
"resolved" "https://registry.npmjs.org/history/-/history-4.10.1.tgz" resolved "https://registry.npmjs.org/history/-/history-4.10.1.tgz"
"version" "4.10.1" integrity sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==
dependencies: dependencies:
"@babel/runtime" "^7.1.2" "@babel/runtime" "^7.1.2"
"loose-envify" "^1.2.0" loose-envify "^1.2.0"
"resolve-pathname" "^3.0.0" resolve-pathname "^3.0.0"
"tiny-invariant" "^1.0.2" tiny-invariant "^1.0.2"
"tiny-warning" "^1.0.0" tiny-warning "^1.0.0"
"value-equal" "^1.0.1" value-equal "^1.0.1"
"hoist-non-react-statics@^3.0.0", "hoist-non-react-statics@^3.1.0", "hoist-non-react-statics@^3.3.0": hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0:
"integrity" "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==" version "3.3.2"
"resolved" "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
"version" "3.3.2" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
dependencies: dependencies:
"react-is" "^16.7.0" react-is "^16.7.0"
"isarray@0.0.1": isarray@0.0.1:
"integrity" "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" version "0.0.1"
"resolved" "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
"version" "0.0.1" integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
"js-tokens@^3.0.0 || ^4.0.0", "js-tokens@^4.0.0": "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
"integrity" "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" version "4.0.0"
"resolved" "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz"
"version" "4.0.0" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
"jsesc@^2.5.1": jsesc@^2.5.1:
"integrity" "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" version "2.5.2"
"resolved" "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz"
"version" "2.5.2" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
"lodash@^4.17.11": lodash@^4.17.11:
"integrity" "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" version "4.17.21"
"resolved" "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
"version" "4.17.21" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
"loose-envify@^1.1.0", "loose-envify@^1.2.0", "loose-envify@^1.3.1", "loose-envify@^1.4.0": loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
"integrity" "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==" version "1.4.0"
"resolved" "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
"version" "1.4.0" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
dependencies: dependencies:
"js-tokens" "^3.0.0 || ^4.0.0" js-tokens "^3.0.0 || ^4.0.0"
"mini-create-react-context@^0.4.0": mini-create-react-context@^0.4.0:
"integrity" "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==" version "0.4.1"
"resolved" "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz" resolved "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz"
"version" "0.4.1" integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==
dependencies: dependencies:
"@babel/runtime" "^7.12.1" "@babel/runtime" "^7.12.1"
"tiny-warning" "^1.0.3" tiny-warning "^1.0.3"
"ms@2.1.2": ms@2.1.2:
"integrity" "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" version "2.1.2"
"resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
"version" "2.1.2" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
"node-fetch@^2.6.12": node-fetch@^2.6.12:
"integrity" "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==" version "2.6.12"
"resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz" resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz"
"version" "2.6.12" integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==
dependencies: dependencies:
"whatwg-url" "^5.0.0" whatwg-url "^5.0.0"
"object-assign@^4.1.1": object-assign@^4.1.1:
"integrity" "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" version "4.1.1"
"resolved" "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
"version" "4.1.1" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
"path-to-regexp@^1.7.0": path-to-regexp@^1.7.0:
"integrity" "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==" version "1.8.0"
"resolved" "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz" resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz"
"version" "1.8.0" integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
dependencies: dependencies:
"isarray" "0.0.1" isarray "0.0.1"
"postcss-value-parser@^4.0.2": postcss-value-parser@^4.0.2:
"integrity" "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" version "4.2.0"
"resolved" "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz"
"version" "4.2.0" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
"prettier@2.7.1": prettier@2.7.1:
"integrity" "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==" version "2.7.1"
"resolved" "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz" resolved "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz"
"version" "2.7.1" integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==
"prop-types@^15.0.0", "prop-types@^15.6.2": prop-types@^15.0.0, prop-types@^15.6.2:
"integrity" "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==" version "15.7.2"
"resolved" "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz"
"version" "15.7.2" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
dependencies: dependencies:
"loose-envify" "^1.4.0" loose-envify "^1.4.0"
"object-assign" "^4.1.1" object-assign "^4.1.1"
"react-is" "^16.8.1" react-is "^16.8.1"
"react-dom@^17.0.2", "react-dom@>= 16.8.0": react-dom@^17.0.2, "react-dom@>= 16.8.0":
"integrity" "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==" version "17.0.2"
"resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz" resolved "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz"
"version" "17.0.2" integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==
dependencies: dependencies:
"loose-envify" "^1.1.0" loose-envify "^1.1.0"
"object-assign" "^4.1.1" object-assign "^4.1.1"
"scheduler" "^0.20.2" scheduler "^0.20.2"
"react-is@^16.6.0": react-is@^16.6.0:
"integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" version "16.13.1"
"resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
"version" "16.13.1" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
"react-is@^16.7.0": react-is@^16.7.0:
"integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" version "16.13.1"
"resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
"version" "16.13.1" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
"react-is@^16.8.1": react-is@^16.8.1:
"integrity" "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" version "16.13.1"
"resolved" "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz"
"version" "16.13.1" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
"react-is@^17.0.2", "react-is@>= 16.8.0": react-is@^17.0.2, "react-is@>= 16.8.0":
"integrity" "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" version "17.0.2"
"resolved" "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz"
"version" "17.0.2" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
"react-router-dom@^5.2.0": react-router-dom@^5.2.0:
"integrity" "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==" version "5.2.0"
"resolved" "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz" resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz"
"version" "5.2.0" integrity sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==
dependencies: dependencies:
"@babel/runtime" "^7.1.2" "@babel/runtime" "^7.1.2"
"history" "^4.9.0" history "^4.9.0"
"loose-envify" "^1.3.1" loose-envify "^1.3.1"
"prop-types" "^15.6.2" prop-types "^15.6.2"
"react-router" "5.2.0" react-router "5.2.0"
"tiny-invariant" "^1.0.2" tiny-invariant "^1.0.2"
"tiny-warning" "^1.0.0" tiny-warning "^1.0.0"
"react-router@5.2.0": react-router@5.2.0:
"integrity" "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==" version "5.2.0"
"resolved" "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz" resolved "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz"
"version" "5.2.0" integrity sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==
dependencies: dependencies:
"@babel/runtime" "^7.1.2" "@babel/runtime" "^7.1.2"
"history" "^4.9.0" history "^4.9.0"
"hoist-non-react-statics" "^3.1.0" hoist-non-react-statics "^3.1.0"
"loose-envify" "^1.3.1" loose-envify "^1.3.1"
"mini-create-react-context" "^0.4.0" mini-create-react-context "^0.4.0"
"path-to-regexp" "^1.7.0" path-to-regexp "^1.7.0"
"prop-types" "^15.6.2" prop-types "^15.6.2"
"react-is" "^16.6.0" react-is "^16.6.0"
"tiny-invariant" "^1.0.2" tiny-invariant "^1.0.2"
"tiny-warning" "^1.0.0" tiny-warning "^1.0.0"
"react@^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", "react@^17.0.2", "react@>= 16.8.0", "react@>=15", "react@>=16", "react@17.0.2": "react@^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0", react@^17.0.2, "react@>= 16.8.0", react@>=15, react@>=16, react@17.0.2:
"integrity" "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==" version "17.0.2"
"resolved" "https://registry.npmjs.org/react/-/react-17.0.2.tgz" resolved "https://registry.npmjs.org/react/-/react-17.0.2.tgz"
"version" "17.0.2" integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==
dependencies: dependencies:
"loose-envify" "^1.1.0" loose-envify "^1.1.0"
"object-assign" "^4.1.1" object-assign "^4.1.1"
"regenerator-runtime@^0.13.4": regenerator-runtime@^0.13.4:
"integrity" "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" version "0.13.9"
"resolved" "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz" resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz"
"version" "0.13.9" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
"resolve-pathname@^3.0.0": resolve-pathname@^3.0.0:
"integrity" "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" version "3.0.0"
"resolved" "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz" resolved "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz"
"version" "3.0.0" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
"scheduler@^0.20.2": scheduler@^0.20.2:
"integrity" "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==" version "0.20.2"
"resolved" "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz" resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz"
"version" "0.20.2" integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==
dependencies: dependencies:
"loose-envify" "^1.1.0" loose-envify "^1.1.0"
"object-assign" "^4.1.1" object-assign "^4.1.1"
"shallowequal@^1.1.0": shallowequal@^1.1.0:
"integrity" "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" version "1.1.0"
"resolved" "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz" resolved "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz"
"version" "1.1.0" integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
"source-map@^0.5.0": source-map@^0.5.0:
"integrity" "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" version "0.5.7"
"resolved" "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz" resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz"
"version" "0.5.7" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
"styled-components@^5.3.0", "styled-components@>= 2": styled-components@^5.3.0, "styled-components@>= 2":
"integrity" "sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==" version "5.3.3"
"resolved" "https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz" resolved "https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz"
"version" "5.3.3" integrity sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==
dependencies: dependencies:
"@babel/helper-module-imports" "^7.0.0" "@babel/helper-module-imports" "^7.0.0"
"@babel/traverse" "^7.4.5" "@babel/traverse" "^7.4.5"
"@emotion/is-prop-valid" "^0.8.8" "@emotion/is-prop-valid" "^0.8.8"
"@emotion/stylis" "^0.8.4" "@emotion/stylis" "^0.8.4"
"@emotion/unitless" "^0.7.4" "@emotion/unitless" "^0.7.4"
"babel-plugin-styled-components" ">= 1.12.0" babel-plugin-styled-components ">= 1.12.0"
"css-to-react-native" "^3.0.0" css-to-react-native "^3.0.0"
"hoist-non-react-statics" "^3.0.0" hoist-non-react-statics "^3.0.0"
"shallowequal" "^1.1.0" shallowequal "^1.1.0"
"supports-color" "^5.5.0" supports-color "^5.5.0"
"supports-color@^5.3.0", "supports-color@^5.5.0": supports-color@^5.3.0, supports-color@^5.5.0:
"integrity" "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==" version "5.5.0"
"resolved" "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz"
"version" "5.5.0" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
dependencies: dependencies:
"has-flag" "^3.0.0" has-flag "^3.0.0"
"tiny-invariant@^1.0.2": tiny-invariant@^1.0.2:
"integrity" "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" version "1.1.0"
"resolved" "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz" resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz"
"version" "1.1.0" integrity sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==
"tiny-warning@^1.0.0", "tiny-warning@^1.0.3": tiny-warning@^1.0.0, tiny-warning@^1.0.3:
"integrity" "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" version "1.0.3"
"resolved" "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz" resolved "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz"
"version" "1.0.3" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
"to-fast-properties@^2.0.0": to-fast-properties@^2.0.0:
"integrity" "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" version "2.0.0"
"resolved" "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz"
"version" "2.0.0" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
"tr46@~0.0.3": tr46@~0.0.3:
"integrity" "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" version "0.0.3"
"resolved" "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz"
"version" "0.0.3" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
"typescript@^4.3.5": typescript@^4.3.5:
"integrity" "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" version "4.3.5"
"resolved" "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz" resolved "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz"
"version" "4.3.5" integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==
"value-equal@^1.0.1": value-equal@^1.0.1:
"integrity" "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" version "1.0.1"
"resolved" "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz" resolved "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz"
"version" "1.0.1" integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==
"webidl-conversions@^3.0.0": webidl-conversions@^3.0.0:
"integrity" "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" version "3.0.1"
"resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz"
"version" "3.0.1" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
"whatwg-url@^5.0.0": whatwg-url@^5.0.0:
"integrity" "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==" version "5.0.0"
"resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz"
"version" "5.0.0" integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==
dependencies: dependencies:
"tr46" "~0.0.3" tr46 "~0.0.3"
"webidl-conversions" "^3.0.0" webidl-conversions "^3.0.0"

View File

@@ -124,6 +124,19 @@ const Features = ({ variables, setVariables }: any) => {
/> />
</Flex> </Flex>
</Flex> </Flex>
<Flex>
<Flex w="100%" justifyContent="start" alignItems="center">
<Text fontSize="sm">Playground:</Text>
</Flex>
<Flex justifyContent="start">
<InputField
variables={variables}
setVariables={setVariables}
inputType={SwitchInputType.DISABLE_PLAYGROUND}
hasReversedValue
/>
</Flex>
</Flex>
</Stack> </Stack>
<Divider paddingY={5} /> <Divider paddingY={5} />
<Text fontSize="md" paddingTop={5} fontWeight="bold" mb={5}> <Text fontSize="md" paddingTop={5} fontWeight="bold" mb={5}>

View File

@@ -84,6 +84,7 @@ export const SwitchInputType = {
DISABLE_STRONG_PASSWORD: 'DISABLE_STRONG_PASSWORD', DISABLE_STRONG_PASSWORD: 'DISABLE_STRONG_PASSWORD',
DISABLE_MULTI_FACTOR_AUTHENTICATION: 'DISABLE_MULTI_FACTOR_AUTHENTICATION', DISABLE_MULTI_FACTOR_AUTHENTICATION: 'DISABLE_MULTI_FACTOR_AUTHENTICATION',
ENFORCE_MULTI_FACTOR_AUTHENTICATION: 'ENFORCE_MULTI_FACTOR_AUTHENTICATION', ENFORCE_MULTI_FACTOR_AUTHENTICATION: 'ENFORCE_MULTI_FACTOR_AUTHENTICATION',
DISABLE_PLAYGROUND: 'DISABLE_PLAYGROUND',
}; };
export const DateInputType = { export const DateInputType = {
@@ -167,6 +168,7 @@ export interface envVarTypes {
ENFORCE_MULTI_FACTOR_AUTHENTICATION: boolean; ENFORCE_MULTI_FACTOR_AUTHENTICATION: boolean;
DEFAULT_AUTHORIZE_RESPONSE_TYPE: string; DEFAULT_AUTHORIZE_RESPONSE_TYPE: string;
DEFAULT_AUTHORIZE_RESPONSE_MODE: string; DEFAULT_AUTHORIZE_RESPONSE_MODE: string;
DISABLE_PLAYGROUND: boolean;
} }
export const envSubViews = { export const envSubViews = {
@@ -220,6 +222,7 @@ export const webhookEventNames = {
'User deleted': 'user.deleted', 'User deleted': 'user.deleted',
'User access enabled': 'user.access_enabled', 'User access enabled': 'user.access_enabled',
'User access revoked': 'user.access_revoked', 'User access revoked': 'user.access_revoked',
'User deactivated': 'user.deactivated',
}; };
export const emailTemplateEventNames = { export const emailTemplateEventNames = {

View File

@@ -73,6 +73,7 @@ export const EnvVariablesQuery = `
ENFORCE_MULTI_FACTOR_AUTHENTICATION ENFORCE_MULTI_FACTOR_AUTHENTICATION
DEFAULT_AUTHORIZE_RESPONSE_TYPE DEFAULT_AUTHORIZE_RESPONSE_TYPE
DEFAULT_AUTHORIZE_RESPONSE_MODE DEFAULT_AUTHORIZE_RESPONSE_MODE
DISABLE_PLAYGROUND
} }
} }
`; `;

View File

@@ -93,6 +93,7 @@ const Environment = () => {
ENFORCE_MULTI_FACTOR_AUTHENTICATION: false, ENFORCE_MULTI_FACTOR_AUTHENTICATION: false,
DEFAULT_AUTHORIZE_RESPONSE_TYPE: '', DEFAULT_AUTHORIZE_RESPONSE_TYPE: '',
DEFAULT_AUTHORIZE_RESPONSE_MODE: '', DEFAULT_AUTHORIZE_RESPONSE_MODE: '',
DISABLE_PLAYGROUND: false,
}); });
const [fieldVisibility, setFieldVisibility] = React.useState< const [fieldVisibility, setFieldVisibility] = React.useState<

View File

@@ -118,7 +118,6 @@ 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">

File diff suppressed because it is too large Load Diff

View File

@@ -5,4 +5,6 @@ const (
AppCookieName = "cookie" AppCookieName = "cookie"
// AdminCookieName is the name of the cookie that is used to store the admin token // AdminCookieName is the name of the cookie that is used to store the admin token
AdminCookieName = "authorizer-admin" AdminCookieName = "authorizer-admin"
// MfaCookieName is the name of the cookie that is used to store the mfa session
MfaCookieName = "mfa"
) )

View File

@@ -163,6 +163,9 @@ const (
// EnvKeyDisablePhoneVerification is key for env variable DISABLE_PHONE_VERIFICATION // EnvKeyDisablePhoneVerification is key for env variable DISABLE_PHONE_VERIFICATION
// this variable is used to disable phone verification // this variable is used to disable phone verification
EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION" EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION"
// EnvKeyDisablePlayGround is key for env variable DISABLE_PLAYGROUND
// this variable will disable or enable playground use in dashboard
EnvKeyDisablePlayGround = "DISABLE_PLAYGROUND"
// Slice variables // Slice variables
// EnvKeyRoles key for env variable ROLES // EnvKeyRoles key for env variable ROLES

View File

@@ -15,4 +15,6 @@ const (
UserAccessEnabledWebhookEvent = `user.access_enabled` UserAccessEnabledWebhookEvent = `user.access_enabled`
// UserDeletedWebhookEvent name for user deleted event // UserDeletedWebhookEvent name for user deleted event
UserDeletedWebhookEvent = `user.deleted` UserDeletedWebhookEvent = `user.deleted`
// UserDeactivatedWebhookEvent name for user deactivated event
UserDeactivatedWebhookEvent = `user.deactivated`
) )

View File

@@ -0,0 +1,89 @@
package cookie
import (
"net/http"
"net/url"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/parsers"
"github.com/gin-gonic/gin"
)
// SetMfaSession sets the mfa session cookie in the response
func SetMfaSession(gc *gin.Context, sessionID string) {
appCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAppCookieSecure)
if err != nil {
log.Debug("Error while getting app cookie secure from env variable: %v", err)
appCookieSecure = true
}
secure := appCookieSecure
httpOnly := appCookieSecure
hostname := parsers.GetHost(gc)
host, _ := parsers.GetHostParts(hostname)
domain := parsers.GetDomainName(hostname)
if domain != "localhost" {
domain = "." + domain
}
// Since app cookie can come from cross site it becomes important to set this in lax mode when insecure.
// Example person using custom UI on their app domain and making request to authorizer domain.
// For more information check:
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
// https://github.com/gin-gonic/gin/blob/master/context.go#L86
// TODO add ability to sameSite = none / strict from dashboard
if !appCookieSecure {
gc.SetSameSite(http.SameSiteLaxMode)
} else {
gc.SetSameSite(http.SameSiteNoneMode)
}
// TODO allow configuring from dashboard
age := 60
gc.SetCookie(constants.MfaCookieName+"_session", sessionID, age, "/", host, secure, httpOnly)
gc.SetCookie(constants.MfaCookieName+"_session_domain", sessionID, age, "/", domain, secure, httpOnly)
}
// DeleteMfaSession deletes the mfa session cookies to expire
func DeleteMfaSession(gc *gin.Context) {
appCookieSecure, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyAppCookieSecure)
if err != nil {
log.Debug("Error while getting app cookie secure from env variable: %v", err)
appCookieSecure = true
}
secure := appCookieSecure
httpOnly := appCookieSecure
hostname := parsers.GetHost(gc)
host, _ := parsers.GetHostParts(hostname)
domain := parsers.GetDomainName(hostname)
if domain != "localhost" {
domain = "." + domain
}
gc.SetSameSite(http.SameSiteNoneMode)
gc.SetCookie(constants.MfaCookieName+"_session", "", -1, "/", host, secure, httpOnly)
gc.SetCookie(constants.MfaCookieName+"_session_domain", "", -1, "/", domain, secure, httpOnly)
}
// GetMfaSession gets the mfa session cookie from context
func GetMfaSession(gc *gin.Context) (string, error) {
var cookie *http.Cookie
var err error
cookie, err = gc.Request.Cookie(constants.MfaCookieName + "_session")
if err != nil {
cookie, err = gc.Request.Cookie(constants.MfaCookieName + "_session_domain")
if err != nil {
return "", err
}
}
decodedValue, err := url.PathUnescape(cookie.Value)
if err != nil {
return "", err
}
return decodedValue, nil
}

View File

@@ -33,12 +33,14 @@ type User struct {
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled" bson:"is_multi_factor_auth_enabled" cql:"is_multi_factor_auth_enabled" dynamo:"is_multi_factor_auth_enabled"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled" bson:"is_multi_factor_auth_enabled" cql:"is_multi_factor_auth_enabled" dynamo:"is_multi_factor_auth_enabled"`
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"` UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
AppData *string `json:"app_data" bson:"app_data" cql:"app_data" dynamo:"app_data"`
} }
func (user *User) AsAPIUser() *model.User { func (user *User) AsAPIUser() *model.User {
isEmailVerified := user.EmailVerifiedAt != nil isEmailVerified := user.EmailVerifiedAt != nil
isPhoneVerified := user.PhoneNumberVerifiedAt != nil isPhoneVerified := user.PhoneNumberVerifiedAt != nil
appDataMap := make(map[string]interface{})
json.Unmarshal([]byte(refs.StringValue(user.AppData)), &appDataMap)
// id := user.ID // id := user.ID
// if strings.Contains(id, Collections.User+"/") { // if strings.Contains(id, Collections.User+"/") {
// id = strings.TrimPrefix(id, Collections.User+"/") // id = strings.TrimPrefix(id, Collections.User+"/")
@@ -63,6 +65,7 @@ func (user *User) AsAPIUser() *model.User {
IsMultiFactorAuthEnabled: user.IsMultiFactorAuthEnabled, IsMultiFactorAuthEnabled: user.IsMultiFactorAuthEnabled,
CreatedAt: refs.NewInt64Ref(user.CreatedAt), CreatedAt: refs.NewInt64Ref(user.CreatedAt),
UpdatedAt: refs.NewInt64Ref(user.UpdatedAt), UpdatedAt: refs.NewInt64Ref(user.UpdatedAt),
AppData: appDataMap,
} }
} }

View File

@@ -74,7 +74,6 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination *mod
var verificationRequest models.VerificationRequest var verificationRequest models.VerificationRequest
err := scanner.Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt) err := scanner.Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt)
if err != nil { if err != nil {
fmt.Println("=> getting error here...", err)
return nil, err return nil, err
} }
verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest()) verificationRequests = append(verificationRequests, verificationRequest.AsAPIVerificationRequest())

View File

@@ -72,7 +72,6 @@ func getEmailTemplate(event string, data map[string]interface{}) (*model.EmailTe
return nil, err return nil, err
} }
subjectString := buf.String() subjectString := buf.String()
return &model.EmailTemplate{ return &model.EmailTemplate{
Template: templateString, Template: templateString,
Subject: subjectString, Subject: subjectString,

15
server/env/env.go vendored
View File

@@ -106,6 +106,8 @@ func InitAllEnv() error {
osDisableMultiFactorAuthentication := os.Getenv(constants.EnvKeyDisableMultiFactorAuthentication) osDisableMultiFactorAuthentication := os.Getenv(constants.EnvKeyDisableMultiFactorAuthentication)
// phone verification var // phone verification var
osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification) osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification)
osDisablePlayground := os.Getenv(constants.EnvKeyDisablePlayGround)
// twilio vars // twilio vars
osTwilioApiKey := os.Getenv(constants.EnvKeyTwilioAPIKey) osTwilioApiKey := os.Getenv(constants.EnvKeyTwilioAPIKey)
osTwilioApiSecret := os.Getenv(constants.EnvKeyTwilioAPISecret) osTwilioApiSecret := os.Getenv(constants.EnvKeyTwilioAPISecret)
@@ -825,6 +827,19 @@ func InitAllEnv() error {
envData[constants.EnvKeyIsSMSServiceEnabled] = true envData[constants.EnvKeyIsSMSServiceEnabled] = true
} }
if _, ok := envData[constants.EnvKeyDisablePlayGround]; !ok {
envData[constants.EnvKeyDisablePlayGround] = osDisablePlayground == "true"
}
if osDisablePlayground != "" {
boolValue, err := strconv.ParseBool(osDisablePlayground)
if err != nil {
return err
}
if boolValue != envData[constants.EnvKeyDisablePlayGround].(bool) {
envData[constants.EnvKeyDisablePlayGround] = boolValue
}
}
err = memorystore.Provider.UpdateEnvStore(envData) err = memorystore.Provider.UpdateEnvStore(envData)
if err != nil { if err != nil {
log.Debug("Error while updating env store: ", err) log.Debug("Error while updating env store: ", err)

View File

@@ -196,7 +196,7 @@ func PersistEnv() error {
envValue := strings.TrimSpace(os.Getenv(key)) envValue := strings.TrimSpace(os.Getenv(key))
if envValue != "" { if envValue != "" {
switch key { switch key {
case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyIsSMSServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure, constants.EnvKeyDisablePhoneVerification: case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyIsSMSServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure, constants.EnvKeyDisablePhoneVerification, constants.EnvKeyDisablePlayGround:
if envValueBool, err := strconv.ParseBool(envValue); err == nil { if envValueBool, err := strconv.ParseBool(envValue); err == nil {
if value.(bool) != envValueBool { if value.(bool) != envValueBool {
storeData[key] = envValueBool storeData[key] = envValueBool

View File

@@ -30,7 +30,7 @@ require (
go.mongodb.org/mongo-driver v1.8.1 go.mongodb.org/mongo-driver v1.8.1
golang.org/x/crypto v0.4.0 golang.org/x/crypto v0.4.0
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/mail.v2 v2.3.1 gopkg.in/mail.v2 v2.3.1

View File

@@ -97,6 +97,7 @@ type ComplexityRoot struct {
DisableLoginPage func(childComplexity int) int DisableLoginPage func(childComplexity int) int
DisableMagicLinkLogin func(childComplexity int) int DisableMagicLinkLogin func(childComplexity int) int
DisableMultiFactorAuthentication func(childComplexity int) int DisableMultiFactorAuthentication func(childComplexity int) int
DisablePlayground func(childComplexity int) int
DisableRedisForEnv func(childComplexity int) int DisableRedisForEnv func(childComplexity int) int
DisableSignUp func(childComplexity int) int DisableSignUp func(childComplexity int) int
DisableStrongPassword func(childComplexity int) int DisableStrongPassword func(childComplexity int) int
@@ -174,6 +175,7 @@ type ComplexityRoot struct {
AdminLogin func(childComplexity int, params model.AdminLoginInput) int AdminLogin func(childComplexity int, params model.AdminLoginInput) int
AdminLogout func(childComplexity int) int AdminLogout func(childComplexity int) int
AdminSignup func(childComplexity int, params model.AdminSignupInput) int AdminSignup func(childComplexity int, params model.AdminSignupInput) int
DeactivateAccount func(childComplexity int) int
DeleteEmailTemplate func(childComplexity int, params model.DeleteEmailTemplateRequest) int DeleteEmailTemplate func(childComplexity int, params model.DeleteEmailTemplateRequest) int
DeleteUser func(childComplexity int, params model.DeleteUserInput) int DeleteUser func(childComplexity int, params model.DeleteUserInput) int
DeleteWebhook func(childComplexity int, params model.WebhookRequest) int DeleteWebhook func(childComplexity int, params model.WebhookRequest) int
@@ -245,6 +247,7 @@ type ComplexityRoot struct {
} }
User struct { User struct {
AppData func(childComplexity int) int
Birthdate func(childComplexity int) int Birthdate func(childComplexity int) int
CreatedAt func(childComplexity int) int CreatedAt func(childComplexity int) int
Email func(childComplexity int) int Email func(childComplexity int) int
@@ -278,6 +281,7 @@ type ComplexityRoot struct {
ValidateSessionResponse struct { ValidateSessionResponse struct {
IsValid func(childComplexity int) int IsValid func(childComplexity int) int
User func(childComplexity int) int
} }
VerificationRequest struct { VerificationRequest struct {
@@ -344,6 +348,7 @@ type MutationResolver interface {
Revoke(ctx context.Context, params model.OAuthRevokeInput) (*model.Response, error) Revoke(ctx context.Context, params model.OAuthRevokeInput) (*model.Response, error)
VerifyOtp(ctx context.Context, params model.VerifyOTPRequest) (*model.AuthResponse, error) VerifyOtp(ctx context.Context, params model.VerifyOTPRequest) (*model.AuthResponse, error)
ResendOtp(ctx context.Context, params model.ResendOTPRequest) (*model.Response, error) ResendOtp(ctx context.Context, params model.ResendOTPRequest) (*model.Response, error)
DeactivateAccount(ctx context.Context) (*model.Response, error)
DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error)
UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error) UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error)
AdminSignup(ctx context.Context, params model.AdminSignupInput) (*model.Response, error) AdminSignup(ctx context.Context, params model.AdminSignupInput) (*model.Response, error)
@@ -695,6 +700,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Env.DisableMultiFactorAuthentication(childComplexity), true return e.complexity.Env.DisableMultiFactorAuthentication(childComplexity), true
case "Env.DISABLE_PLAYGROUND":
if e.complexity.Env.DisablePlayground == nil {
break
}
return e.complexity.Env.DisablePlayground(childComplexity), true
case "Env.DISABLE_REDIS_FOR_ENV": case "Env.DISABLE_REDIS_FOR_ENV":
if e.complexity.Env.DisableRedisForEnv == nil { if e.complexity.Env.DisableRedisForEnv == nil {
break break
@@ -1149,6 +1161,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Mutation.AdminSignup(childComplexity, args["params"].(model.AdminSignupInput)), true return e.complexity.Mutation.AdminSignup(childComplexity, args["params"].(model.AdminSignupInput)), true
case "Mutation.deactivate_account":
if e.complexity.Mutation.DeactivateAccount == nil {
break
}
return e.complexity.Mutation.DeactivateAccount(childComplexity), true
case "Mutation._delete_email_template": case "Mutation._delete_email_template":
if e.complexity.Mutation.DeleteEmailTemplate == nil { if e.complexity.Mutation.DeleteEmailTemplate == nil {
break break
@@ -1695,6 +1714,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.TestEndpointResponse.Response(childComplexity), true return e.complexity.TestEndpointResponse.Response(childComplexity), true
case "User.app_data":
if e.complexity.User.AppData == nil {
break
}
return e.complexity.User.AppData(childComplexity), true
case "User.birthdate": case "User.birthdate":
if e.complexity.User.Birthdate == nil { if e.complexity.User.Birthdate == nil {
break break
@@ -1863,6 +1889,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.ValidateSessionResponse.IsValid(childComplexity), true return e.complexity.ValidateSessionResponse.IsValid(childComplexity), true
case "ValidateSessionResponse.user":
if e.complexity.ValidateSessionResponse.User == nil {
break
}
return e.complexity.ValidateSessionResponse.User(childComplexity), true
case "VerificationRequest.created_at": case "VerificationRequest.created_at":
if e.complexity.VerificationRequest.CreatedAt == nil { if e.complexity.VerificationRequest.CreatedAt == nil {
break break
@@ -2229,6 +2262,7 @@ type User {
updated_at: Int64 updated_at: Int64
revoked_timestamp: Int64 revoked_timestamp: Int64
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
app_data: Map
} }
type Users { type Users {
@@ -2349,6 +2383,7 @@ type Env {
ADMIN_COOKIE_SECURE: Boolean! ADMIN_COOKIE_SECURE: Boolean!
DEFAULT_AUTHORIZE_RESPONSE_TYPE: String DEFAULT_AUTHORIZE_RESPONSE_TYPE: String
DEFAULT_AUTHORIZE_RESPONSE_MODE: String DEFAULT_AUTHORIZE_RESPONSE_MODE: String
DISABLE_PLAYGROUND: Boolean!
} }
type ValidateJWTTokenResponse { type ValidateJWTTokenResponse {
@@ -2358,6 +2393,7 @@ type ValidateJWTTokenResponse {
type ValidateSessionResponse { type ValidateSessionResponse {
is_valid: Boolean! is_valid: Boolean!
user: User!
} }
type GenerateJWTKeysResponse { type GenerateJWTKeysResponse {
@@ -2470,6 +2506,7 @@ input UpdateEnvInput {
ORGANIZATION_LOGO: String ORGANIZATION_LOGO: String
DEFAULT_AUTHORIZE_RESPONSE_TYPE: String DEFAULT_AUTHORIZE_RESPONSE_TYPE: String
DEFAULT_AUTHORIZE_RESPONSE_MODE: String DEFAULT_AUTHORIZE_RESPONSE_MODE: String
DISABLE_PLAYGROUND: Boolean
} }
input AdminLoginInput { input AdminLoginInput {
@@ -2500,6 +2537,7 @@ input MobileSignUpInput {
# it is used to get code for an on-going auth process during login # it is used to get code for an on-going auth process during login
# and use that code for setting ` + "`" + `c_hash` + "`" + ` in id_token # and use that code for setting ` + "`" + `c_hash` + "`" + ` in id_token
state: String state: String
app_data: Map
} }
input SignUpInput { input SignUpInput {
@@ -2522,6 +2560,7 @@ input SignUpInput {
# it is used to get code for an on-going auth process during login # it is used to get code for an on-going auth process during login
# and use that code for setting ` + "`" + `c_hash` + "`" + ` in id_token # and use that code for setting ` + "`" + `c_hash` + "`" + ` in id_token
state: String state: String
app_data: Map
} }
input LoginInput { input LoginInput {
@@ -2577,6 +2616,7 @@ input UpdateProfileInput {
phone_number: String phone_number: String
picture: String picture: String
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
app_data: Map
} }
input UpdateUserInput { input UpdateUserInput {
@@ -2593,6 +2633,7 @@ input UpdateUserInput {
picture: String picture: String
roles: [String] roles: [String]
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
app_data: Map
} }
input ForgotPasswordInput { input ForgotPasswordInput {
@@ -2690,6 +2731,7 @@ input WebhookRequest {
input TestEndpointRequest { input TestEndpointRequest {
endpoint: String! endpoint: String!
event_name: String! event_name: String!
event_description: String
headers: Map headers: Map
} }
@@ -2756,6 +2798,7 @@ type Mutation {
revoke(params: OAuthRevokeInput!): Response! revoke(params: OAuthRevokeInput!): Response!
verify_otp(params: VerifyOTPRequest!): AuthResponse! verify_otp(params: VerifyOTPRequest!): AuthResponse!
resend_otp(params: ResendOTPRequest!): Response! resend_otp(params: ResendOTPRequest!): Response!
deactivate_account: Response!
# admin only apis # admin only apis
_delete_user(params: DeleteUserInput!): Response! _delete_user(params: DeleteUserInput!): Response!
_update_user(params: UpdateUserInput!): User! _update_user(params: UpdateUserInput!): User!
@@ -3803,6 +3846,8 @@ func (ec *executionContext) fieldContext_AuthResponse_user(ctx context.Context,
return ec.fieldContext_User_revoked_timestamp(ctx, field) return ec.fieldContext_User_revoked_timestamp(ctx, field)
case "is_multi_factor_auth_enabled": case "is_multi_factor_auth_enabled":
return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
case "app_data":
return ec.fieldContext_User_app_data(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type User", field.Name) return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
}, },
@@ -6766,6 +6811,50 @@ func (ec *executionContext) fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx
return fc, nil return fc, nil
} }
func (ec *executionContext) _Env_DISABLE_PLAYGROUND(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Env_DISABLE_PLAYGROUND(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.DisablePlayground, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(bool)
fc.Result = res
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Env_DISABLE_PLAYGROUND(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Boolean does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Error_message(ctx context.Context, field graphql.CollectedField, obj *model.Error) (ret graphql.Marshaler) { func (ec *executionContext) _Error_message(ctx context.Context, field graphql.CollectedField, obj *model.Error) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Error_message(ctx, field) fc, err := ec.fieldContext_Error_message(ctx, field)
if err != nil { if err != nil {
@@ -7098,6 +7187,8 @@ func (ec *executionContext) fieldContext_InviteMembersResponse_Users(ctx context
return ec.fieldContext_User_revoked_timestamp(ctx, field) return ec.fieldContext_User_revoked_timestamp(ctx, field)
case "is_multi_factor_auth_enabled": case "is_multi_factor_auth_enabled":
return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
case "app_data":
return ec.fieldContext_User_app_data(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type User", field.Name) return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
}, },
@@ -8664,6 +8755,54 @@ func (ec *executionContext) fieldContext_Mutation_resend_otp(ctx context.Context
return fc, nil return fc, nil
} }
func (ec *executionContext) _Mutation_deactivate_account(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Mutation_deactivate_account(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 ec.resolvers.Mutation().DeactivateAccount(rctx)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*model.Response)
fc.Result = res
return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Mutation_deactivate_account(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Mutation",
Field: field,
IsMethod: true,
IsResolver: true,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "message":
return ec.fieldContext_Response_message(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type Response", field.Name)
},
}
return fc, nil
}
func (ec *executionContext) _Mutation__delete_user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { func (ec *executionContext) _Mutation__delete_user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Mutation__delete_user(ctx, field) fc, err := ec.fieldContext_Mutation__delete_user(ctx, field)
if err != nil { if err != nil {
@@ -8800,6 +8939,8 @@ func (ec *executionContext) fieldContext_Mutation__update_user(ctx context.Conte
return ec.fieldContext_User_revoked_timestamp(ctx, field) return ec.fieldContext_User_revoked_timestamp(ctx, field)
case "is_multi_factor_auth_enabled": case "is_multi_factor_auth_enabled":
return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
case "app_data":
return ec.fieldContext_User_app_data(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type User", field.Name) return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
}, },
@@ -10102,6 +10243,8 @@ func (ec *executionContext) fieldContext_Query_profile(ctx context.Context, fiel
return ec.fieldContext_User_revoked_timestamp(ctx, field) return ec.fieldContext_User_revoked_timestamp(ctx, field)
case "is_multi_factor_auth_enabled": case "is_multi_factor_auth_enabled":
return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
case "app_data":
return ec.fieldContext_User_app_data(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type User", field.Name) return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
}, },
@@ -10211,6 +10354,8 @@ func (ec *executionContext) fieldContext_Query_validate_session(ctx context.Cont
switch field.Name { switch field.Name {
case "is_valid": case "is_valid":
return ec.fieldContext_ValidateSessionResponse_is_valid(ctx, field) return ec.fieldContext_ValidateSessionResponse_is_valid(ctx, field)
case "user":
return ec.fieldContext_ValidateSessionResponse_user(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type ValidateSessionResponse", field.Name) return nil, fmt.Errorf("no field named %q was found under type ValidateSessionResponse", field.Name)
}, },
@@ -10367,6 +10512,8 @@ func (ec *executionContext) fieldContext_Query__user(ctx context.Context, field
return ec.fieldContext_User_revoked_timestamp(ctx, field) return ec.fieldContext_User_revoked_timestamp(ctx, field)
case "is_multi_factor_auth_enabled": case "is_multi_factor_auth_enabled":
return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
case "app_data":
return ec.fieldContext_User_app_data(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type User", field.Name) return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
}, },
@@ -10655,6 +10802,8 @@ func (ec *executionContext) fieldContext_Query__env(ctx context.Context, field g
return ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(ctx, field) return ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(ctx, field)
case "DEFAULT_AUTHORIZE_RESPONSE_MODE": case "DEFAULT_AUTHORIZE_RESPONSE_MODE":
return ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx, field) return ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx, field)
case "DISABLE_PLAYGROUND":
return ec.fieldContext_Env_DISABLE_PLAYGROUND(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type Env", field.Name) return nil, fmt.Errorf("no field named %q was found under type Env", field.Name)
}, },
@@ -12228,6 +12377,47 @@ func (ec *executionContext) fieldContext_User_is_multi_factor_auth_enabled(ctx c
return fc, nil return fc, nil
} }
func (ec *executionContext) _User_app_data(ctx context.Context, field graphql.CollectedField, obj *model.User) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_User_app_data(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.AppData, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(map[string]interface{})
fc.Result = res
return ec.marshalOMap2map(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_User_app_data(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "User",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Map does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Users_pagination(ctx context.Context, field graphql.CollectedField, obj *model.Users) (ret graphql.Marshaler) { func (ec *executionContext) _Users_pagination(ctx context.Context, field graphql.CollectedField, obj *model.Users) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Users_pagination(ctx, field) fc, err := ec.fieldContext_Users_pagination(ctx, field)
if err != nil { if err != nil {
@@ -12359,6 +12549,8 @@ func (ec *executionContext) fieldContext_Users_users(ctx context.Context, field
return ec.fieldContext_User_revoked_timestamp(ctx, field) return ec.fieldContext_User_revoked_timestamp(ctx, field)
case "is_multi_factor_auth_enabled": case "is_multi_factor_auth_enabled":
return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field) return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
case "app_data":
return ec.fieldContext_User_app_data(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type User", field.Name) return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
}, },
@@ -12495,6 +12687,92 @@ func (ec *executionContext) fieldContext_ValidateSessionResponse_is_valid(ctx co
return fc, nil return fc, nil
} }
func (ec *executionContext) _ValidateSessionResponse_user(ctx context.Context, field graphql.CollectedField, obj *model.ValidateSessionResponse) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_ValidateSessionResponse_user(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.User, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*model.User)
fc.Result = res
return ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_ValidateSessionResponse_user(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "ValidateSessionResponse",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
case "id":
return ec.fieldContext_User_id(ctx, field)
case "email":
return ec.fieldContext_User_email(ctx, field)
case "email_verified":
return ec.fieldContext_User_email_verified(ctx, field)
case "signup_methods":
return ec.fieldContext_User_signup_methods(ctx, field)
case "given_name":
return ec.fieldContext_User_given_name(ctx, field)
case "family_name":
return ec.fieldContext_User_family_name(ctx, field)
case "middle_name":
return ec.fieldContext_User_middle_name(ctx, field)
case "nickname":
return ec.fieldContext_User_nickname(ctx, field)
case "preferred_username":
return ec.fieldContext_User_preferred_username(ctx, field)
case "gender":
return ec.fieldContext_User_gender(ctx, field)
case "birthdate":
return ec.fieldContext_User_birthdate(ctx, field)
case "phone_number":
return ec.fieldContext_User_phone_number(ctx, field)
case "phone_number_verified":
return ec.fieldContext_User_phone_number_verified(ctx, field)
case "picture":
return ec.fieldContext_User_picture(ctx, field)
case "roles":
return ec.fieldContext_User_roles(ctx, field)
case "created_at":
return ec.fieldContext_User_created_at(ctx, field)
case "updated_at":
return ec.fieldContext_User_updated_at(ctx, field)
case "revoked_timestamp":
return ec.fieldContext_User_revoked_timestamp(ctx, field)
case "is_multi_factor_auth_enabled":
return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
case "app_data":
return ec.fieldContext_User_app_data(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
},
}
return fc, nil
}
func (ec *executionContext) _VerificationRequest_id(ctx context.Context, field graphql.CollectedField, obj *model.VerificationRequest) (ret graphql.Marshaler) { func (ec *executionContext) _VerificationRequest_id(ctx context.Context, field graphql.CollectedField, obj *model.VerificationRequest) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_VerificationRequest_id(ctx, field) fc, err := ec.fieldContext_VerificationRequest_id(ctx, field)
if err != nil { if err != nil {
@@ -16200,7 +16478,7 @@ func (ec *executionContext) unmarshalInputMobileSignUpInput(ctx context.Context,
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "password", "confirm_password", "roles", "scope", "redirect_uri", "is_multi_factor_auth_enabled", "state"} fieldsInOrder := [...]string{"email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "password", "confirm_password", "roles", "scope", "redirect_uri", "is_multi_factor_auth_enabled", "state", "app_data"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -16335,6 +16613,14 @@ func (ec *executionContext) unmarshalInputMobileSignUpInput(ctx context.Context,
if err != nil { if err != nil {
return it, err return it, err
} }
case "app_data":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("app_data"))
it.AppData, err = ec.unmarshalOMap2map(ctx, v)
if err != nil {
return it, err
}
} }
} }
@@ -16608,7 +16894,7 @@ func (ec *executionContext) unmarshalInputSignUpInput(ctx context.Context, obj i
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "password", "confirm_password", "roles", "scope", "redirect_uri", "is_multi_factor_auth_enabled", "state"} fieldsInOrder := [...]string{"email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "password", "confirm_password", "roles", "scope", "redirect_uri", "is_multi_factor_auth_enabled", "state", "app_data"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -16743,6 +17029,14 @@ func (ec *executionContext) unmarshalInputSignUpInput(ctx context.Context, obj i
if err != nil { if err != nil {
return it, err return it, err
} }
case "app_data":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("app_data"))
it.AppData, err = ec.unmarshalOMap2map(ctx, v)
if err != nil {
return it, err
}
} }
} }
@@ -16756,7 +17050,7 @@ func (ec *executionContext) unmarshalInputTestEndpointRequest(ctx context.Contex
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"endpoint", "event_name", "headers"} fieldsInOrder := [...]string{"endpoint", "event_name", "event_description", "headers"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -16779,6 +17073,14 @@ func (ec *executionContext) unmarshalInputTestEndpointRequest(ctx context.Contex
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 "headers": case "headers":
var err error var err error
@@ -16888,7 +17190,7 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"ACCESS_TOKEN_EXPIRY_TIME", "ADMIN_SECRET", "CUSTOM_ACCESS_TOKEN_SCRIPT", "OLD_ADMIN_SECRET", "SMTP_HOST", "SMTP_PORT", "SMTP_USERNAME", "SMTP_PASSWORD", "SMTP_LOCAL_NAME", "SENDER_EMAIL", "SENDER_NAME", "JWT_TYPE", "JWT_SECRET", "JWT_PRIVATE_KEY", "JWT_PUBLIC_KEY", "ALLOWED_ORIGINS", "APP_URL", "RESET_PASSWORD_URL", "APP_COOKIE_SECURE", "ADMIN_COOKIE_SECURE", "DISABLE_EMAIL_VERIFICATION", "DISABLE_BASIC_AUTHENTICATION", "DISABLE_MAGIC_LINK_LOGIN", "DISABLE_LOGIN_PAGE", "DISABLE_SIGN_UP", "DISABLE_REDIS_FOR_ENV", "DISABLE_STRONG_PASSWORD", "DISABLE_MULTI_FACTOR_AUTHENTICATION", "ENFORCE_MULTI_FACTOR_AUTHENTICATION", "ROLES", "PROTECTED_ROLES", "DEFAULT_ROLES", "JWT_ROLE_CLAIM", "GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", "GITHUB_CLIENT_ID", "GITHUB_CLIENT_SECRET", "FACEBOOK_CLIENT_ID", "FACEBOOK_CLIENT_SECRET", "LINKEDIN_CLIENT_ID", "LINKEDIN_CLIENT_SECRET", "APPLE_CLIENT_ID", "APPLE_CLIENT_SECRET", "TWITTER_CLIENT_ID", "TWITTER_CLIENT_SECRET", "MICROSOFT_CLIENT_ID", "MICROSOFT_CLIENT_SECRET", "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID", "ORGANIZATION_NAME", "ORGANIZATION_LOGO", "DEFAULT_AUTHORIZE_RESPONSE_TYPE", "DEFAULT_AUTHORIZE_RESPONSE_MODE"} fieldsInOrder := [...]string{"ACCESS_TOKEN_EXPIRY_TIME", "ADMIN_SECRET", "CUSTOM_ACCESS_TOKEN_SCRIPT", "OLD_ADMIN_SECRET", "SMTP_HOST", "SMTP_PORT", "SMTP_USERNAME", "SMTP_PASSWORD", "SMTP_LOCAL_NAME", "SENDER_EMAIL", "SENDER_NAME", "JWT_TYPE", "JWT_SECRET", "JWT_PRIVATE_KEY", "JWT_PUBLIC_KEY", "ALLOWED_ORIGINS", "APP_URL", "RESET_PASSWORD_URL", "APP_COOKIE_SECURE", "ADMIN_COOKIE_SECURE", "DISABLE_EMAIL_VERIFICATION", "DISABLE_BASIC_AUTHENTICATION", "DISABLE_MAGIC_LINK_LOGIN", "DISABLE_LOGIN_PAGE", "DISABLE_SIGN_UP", "DISABLE_REDIS_FOR_ENV", "DISABLE_STRONG_PASSWORD", "DISABLE_MULTI_FACTOR_AUTHENTICATION", "ENFORCE_MULTI_FACTOR_AUTHENTICATION", "ROLES", "PROTECTED_ROLES", "DEFAULT_ROLES", "JWT_ROLE_CLAIM", "GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", "GITHUB_CLIENT_ID", "GITHUB_CLIENT_SECRET", "FACEBOOK_CLIENT_ID", "FACEBOOK_CLIENT_SECRET", "LINKEDIN_CLIENT_ID", "LINKEDIN_CLIENT_SECRET", "APPLE_CLIENT_ID", "APPLE_CLIENT_SECRET", "TWITTER_CLIENT_ID", "TWITTER_CLIENT_SECRET", "MICROSOFT_CLIENT_ID", "MICROSOFT_CLIENT_SECRET", "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID", "ORGANIZATION_NAME", "ORGANIZATION_LOGO", "DEFAULT_AUTHORIZE_RESPONSE_TYPE", "DEFAULT_AUTHORIZE_RESPONSE_MODE", "DISABLE_PLAYGROUND"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -17311,6 +17613,14 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
if err != nil { if err != nil {
return it, err return it, err
} }
case "DISABLE_PLAYGROUND":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("DISABLE_PLAYGROUND"))
it.DisablePlayground, err = ec.unmarshalOBoolean2ᚖbool(ctx, v)
if err != nil {
return it, err
}
} }
} }
@@ -17324,7 +17634,7 @@ func (ec *executionContext) unmarshalInputUpdateProfileInput(ctx context.Context
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"old_password", "new_password", "confirm_new_password", "email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "is_multi_factor_auth_enabled"} fieldsInOrder := [...]string{"old_password", "new_password", "confirm_new_password", "email", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "is_multi_factor_auth_enabled", "app_data"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -17435,6 +17745,14 @@ func (ec *executionContext) unmarshalInputUpdateProfileInput(ctx context.Context
if err != nil { if err != nil {
return it, err return it, err
} }
case "app_data":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("app_data"))
it.AppData, err = ec.unmarshalOMap2map(ctx, v)
if err != nil {
return it, err
}
} }
} }
@@ -17448,7 +17766,7 @@ func (ec *executionContext) unmarshalInputUpdateUserInput(ctx context.Context, o
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"id", "email", "email_verified", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "roles", "is_multi_factor_auth_enabled"} fieldsInOrder := [...]string{"id", "email", "email_verified", "given_name", "family_name", "middle_name", "nickname", "gender", "birthdate", "phone_number", "picture", "roles", "is_multi_factor_auth_enabled", "app_data"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -17559,6 +17877,14 @@ func (ec *executionContext) unmarshalInputUpdateUserInput(ctx context.Context, o
if err != nil { if err != nil {
return it, err return it, err
} }
case "app_data":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("app_data"))
it.AppData, err = ec.unmarshalOMap2map(ctx, v)
if err != nil {
return it, err
}
} }
} }
@@ -18285,6 +18611,13 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, obj
out.Values[i] = ec._Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx, field, obj) out.Values[i] = ec._Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx, field, obj)
case "DISABLE_PLAYGROUND":
out.Values[i] = ec._Env_DISABLE_PLAYGROUND(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
default: default:
panic("unknown field " + strconv.Quote(field.Name)) panic("unknown field " + strconv.Quote(field.Name))
} }
@@ -18667,6 +19000,15 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
return ec._Mutation_resend_otp(ctx, field) return ec._Mutation_resend_otp(ctx, field)
}) })
if out.Values[i] == graphql.Null {
invalids++
}
case "deactivate_account":
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
return ec._Mutation_deactivate_account(ctx, field)
})
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
invalids++ invalids++
} }
@@ -19465,6 +19807,10 @@ func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj
out.Values[i] = ec._User_is_multi_factor_auth_enabled(ctx, field, obj) out.Values[i] = ec._User_is_multi_factor_auth_enabled(ctx, field, obj)
case "app_data":
out.Values[i] = ec._User_app_data(ctx, field, obj)
default: default:
panic("unknown field " + strconv.Quote(field.Name)) panic("unknown field " + strconv.Quote(field.Name))
} }
@@ -19557,6 +19903,13 @@ func (ec *executionContext) _ValidateSessionResponse(ctx context.Context, sel as
out.Values[i] = ec._ValidateSessionResponse_is_valid(ctx, field, obj) out.Values[i] = ec._ValidateSessionResponse_is_valid(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "user":
out.Values[i] = ec._ValidateSessionResponse_user(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
invalids++ invalids++
} }

View File

@@ -121,6 +121,7 @@ type Env struct {
AdminCookieSecure bool `json:"ADMIN_COOKIE_SECURE"` AdminCookieSecure bool `json:"ADMIN_COOKIE_SECURE"`
DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE"` DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE"`
DefaultAuthorizeResponseMode *string `json:"DEFAULT_AUTHORIZE_RESPONSE_MODE"` DefaultAuthorizeResponseMode *string `json:"DEFAULT_AUTHORIZE_RESPONSE_MODE"`
DisablePlayground bool `json:"DISABLE_PLAYGROUND"`
} }
type Error struct { type Error struct {
@@ -207,22 +208,23 @@ type MobileLoginInput struct {
} }
type MobileSignUpInput struct { type MobileSignUpInput struct {
Email *string `json:"email"` Email *string `json:"email"`
GivenName *string `json:"given_name"` GivenName *string `json:"given_name"`
FamilyName *string `json:"family_name"` FamilyName *string `json:"family_name"`
MiddleName *string `json:"middle_name"` MiddleName *string `json:"middle_name"`
Nickname *string `json:"nickname"` Nickname *string `json:"nickname"`
Gender *string `json:"gender"` Gender *string `json:"gender"`
Birthdate *string `json:"birthdate"` Birthdate *string `json:"birthdate"`
PhoneNumber string `json:"phone_number"` PhoneNumber string `json:"phone_number"`
Picture *string `json:"picture"` Picture *string `json:"picture"`
Password string `json:"password"` Password string `json:"password"`
ConfirmPassword string `json:"confirm_password"` ConfirmPassword string `json:"confirm_password"`
Roles []string `json:"roles"` Roles []string `json:"roles"`
Scope []string `json:"scope"` Scope []string `json:"scope"`
RedirectURI *string `json:"redirect_uri"` RedirectURI *string `json:"redirect_uri"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
State *string `json:"state"` State *string `json:"state"`
AppData map[string]interface{} `json:"app_data"`
} }
type OAuthRevokeInput struct { type OAuthRevokeInput struct {
@@ -282,28 +284,30 @@ type SessionQueryInput struct {
} }
type SignUpInput struct { type SignUpInput struct {
Email string `json:"email"` Email string `json:"email"`
GivenName *string `json:"given_name"` GivenName *string `json:"given_name"`
FamilyName *string `json:"family_name"` FamilyName *string `json:"family_name"`
MiddleName *string `json:"middle_name"` MiddleName *string `json:"middle_name"`
Nickname *string `json:"nickname"` Nickname *string `json:"nickname"`
Gender *string `json:"gender"` Gender *string `json:"gender"`
Birthdate *string `json:"birthdate"` Birthdate *string `json:"birthdate"`
PhoneNumber *string `json:"phone_number"` PhoneNumber *string `json:"phone_number"`
Picture *string `json:"picture"` Picture *string `json:"picture"`
Password string `json:"password"` Password string `json:"password"`
ConfirmPassword string `json:"confirm_password"` ConfirmPassword string `json:"confirm_password"`
Roles []string `json:"roles"` Roles []string `json:"roles"`
Scope []string `json:"scope"` Scope []string `json:"scope"`
RedirectURI *string `json:"redirect_uri"` RedirectURI *string `json:"redirect_uri"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
State *string `json:"state"` State *string `json:"state"`
AppData map[string]interface{} `json:"app_data"`
} }
type TestEndpointRequest struct { type TestEndpointRequest struct {
Endpoint string `json:"endpoint"` Endpoint string `json:"endpoint"`
EventName string `json:"event_name"` EventName string `json:"event_name"`
Headers map[string]interface{} `json:"headers"` EventDescription *string `json:"event_description"`
Headers map[string]interface{} `json:"headers"`
} }
type TestEndpointResponse struct { type TestEndpointResponse struct {
@@ -376,38 +380,41 @@ type UpdateEnvInput struct {
OrganizationLogo *string `json:"ORGANIZATION_LOGO"` OrganizationLogo *string `json:"ORGANIZATION_LOGO"`
DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE"` DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE"`
DefaultAuthorizeResponseMode *string `json:"DEFAULT_AUTHORIZE_RESPONSE_MODE"` DefaultAuthorizeResponseMode *string `json:"DEFAULT_AUTHORIZE_RESPONSE_MODE"`
DisablePlayground *bool `json:"DISABLE_PLAYGROUND"`
} }
type UpdateProfileInput struct { type UpdateProfileInput struct {
OldPassword *string `json:"old_password"` OldPassword *string `json:"old_password"`
NewPassword *string `json:"new_password"` NewPassword *string `json:"new_password"`
ConfirmNewPassword *string `json:"confirm_new_password"` ConfirmNewPassword *string `json:"confirm_new_password"`
Email *string `json:"email"` Email *string `json:"email"`
GivenName *string `json:"given_name"` GivenName *string `json:"given_name"`
FamilyName *string `json:"family_name"` FamilyName *string `json:"family_name"`
MiddleName *string `json:"middle_name"` MiddleName *string `json:"middle_name"`
Nickname *string `json:"nickname"` Nickname *string `json:"nickname"`
Gender *string `json:"gender"` Gender *string `json:"gender"`
Birthdate *string `json:"birthdate"` Birthdate *string `json:"birthdate"`
PhoneNumber *string `json:"phone_number"` PhoneNumber *string `json:"phone_number"`
Picture *string `json:"picture"` Picture *string `json:"picture"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
AppData map[string]interface{} `json:"app_data"`
} }
type UpdateUserInput struct { type UpdateUserInput struct {
ID string `json:"id"` ID string `json:"id"`
Email *string `json:"email"` Email *string `json:"email"`
EmailVerified *bool `json:"email_verified"` EmailVerified *bool `json:"email_verified"`
GivenName *string `json:"given_name"` GivenName *string `json:"given_name"`
FamilyName *string `json:"family_name"` FamilyName *string `json:"family_name"`
MiddleName *string `json:"middle_name"` MiddleName *string `json:"middle_name"`
Nickname *string `json:"nickname"` Nickname *string `json:"nickname"`
Gender *string `json:"gender"` Gender *string `json:"gender"`
Birthdate *string `json:"birthdate"` Birthdate *string `json:"birthdate"`
PhoneNumber *string `json:"phone_number"` PhoneNumber *string `json:"phone_number"`
Picture *string `json:"picture"` Picture *string `json:"picture"`
Roles []*string `json:"roles"` Roles []*string `json:"roles"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
AppData map[string]interface{} `json:"app_data"`
} }
type UpdateWebhookRequest struct { type UpdateWebhookRequest struct {
@@ -420,25 +427,26 @@ type UpdateWebhookRequest struct {
} }
type User struct { type User struct {
ID string `json:"id"` ID string `json:"id"`
Email string `json:"email"` Email string `json:"email"`
EmailVerified bool `json:"email_verified"` EmailVerified bool `json:"email_verified"`
SignupMethods string `json:"signup_methods"` SignupMethods string `json:"signup_methods"`
GivenName *string `json:"given_name"` GivenName *string `json:"given_name"`
FamilyName *string `json:"family_name"` FamilyName *string `json:"family_name"`
MiddleName *string `json:"middle_name"` MiddleName *string `json:"middle_name"`
Nickname *string `json:"nickname"` Nickname *string `json:"nickname"`
PreferredUsername *string `json:"preferred_username"` PreferredUsername *string `json:"preferred_username"`
Gender *string `json:"gender"` Gender *string `json:"gender"`
Birthdate *string `json:"birthdate"` Birthdate *string `json:"birthdate"`
PhoneNumber *string `json:"phone_number"` PhoneNumber *string `json:"phone_number"`
PhoneNumberVerified *bool `json:"phone_number_verified"` PhoneNumberVerified *bool `json:"phone_number_verified"`
Picture *string `json:"picture"` Picture *string `json:"picture"`
Roles []string `json:"roles"` Roles []string `json:"roles"`
CreatedAt *int64 `json:"created_at"` CreatedAt *int64 `json:"created_at"`
UpdatedAt *int64 `json:"updated_at"` UpdatedAt *int64 `json:"updated_at"`
RevokedTimestamp *int64 `json:"revoked_timestamp"` RevokedTimestamp *int64 `json:"revoked_timestamp"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
AppData map[string]interface{} `json:"app_data"`
} }
type Users struct { type Users struct {
@@ -463,7 +471,8 @@ type ValidateSessionInput struct {
} }
type ValidateSessionResponse struct { type ValidateSessionResponse struct {
IsValid bool `json:"is_valid"` IsValid bool `json:"is_valid"`
User *User `json:"user"`
} }
type VerificationRequest struct { type VerificationRequest struct {

View File

@@ -51,6 +51,7 @@ type User {
updated_at: Int64 updated_at: Int64
revoked_timestamp: Int64 revoked_timestamp: Int64
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
app_data: Map
} }
type Users { type Users {
@@ -171,6 +172,7 @@ type Env {
ADMIN_COOKIE_SECURE: Boolean! ADMIN_COOKIE_SECURE: Boolean!
DEFAULT_AUTHORIZE_RESPONSE_TYPE: String DEFAULT_AUTHORIZE_RESPONSE_TYPE: String
DEFAULT_AUTHORIZE_RESPONSE_MODE: String DEFAULT_AUTHORIZE_RESPONSE_MODE: String
DISABLE_PLAYGROUND: Boolean!
} }
type ValidateJWTTokenResponse { type ValidateJWTTokenResponse {
@@ -180,6 +182,7 @@ type ValidateJWTTokenResponse {
type ValidateSessionResponse { type ValidateSessionResponse {
is_valid: Boolean! is_valid: Boolean!
user: User!
} }
type GenerateJWTKeysResponse { type GenerateJWTKeysResponse {
@@ -292,6 +295,7 @@ input UpdateEnvInput {
ORGANIZATION_LOGO: String ORGANIZATION_LOGO: String
DEFAULT_AUTHORIZE_RESPONSE_TYPE: String DEFAULT_AUTHORIZE_RESPONSE_TYPE: String
DEFAULT_AUTHORIZE_RESPONSE_MODE: String DEFAULT_AUTHORIZE_RESPONSE_MODE: String
DISABLE_PLAYGROUND: Boolean
} }
input AdminLoginInput { input AdminLoginInput {
@@ -322,6 +326,7 @@ input MobileSignUpInput {
# it is used to get code for an on-going auth process during login # it is used to get code for an on-going auth process during login
# and use that code for setting `c_hash` in id_token # and use that code for setting `c_hash` in id_token
state: String state: String
app_data: Map
} }
input SignUpInput { input SignUpInput {
@@ -344,6 +349,7 @@ input SignUpInput {
# it is used to get code for an on-going auth process during login # it is used to get code for an on-going auth process during login
# and use that code for setting `c_hash` in id_token # and use that code for setting `c_hash` in id_token
state: String state: String
app_data: Map
} }
input LoginInput { input LoginInput {
@@ -399,6 +405,7 @@ input UpdateProfileInput {
phone_number: String phone_number: String
picture: String picture: String
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
app_data: Map
} }
input UpdateUserInput { input UpdateUserInput {
@@ -415,6 +422,7 @@ input UpdateUserInput {
picture: String picture: String
roles: [String] roles: [String]
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
app_data: Map
} }
input ForgotPasswordInput { input ForgotPasswordInput {
@@ -512,6 +520,7 @@ input WebhookRequest {
input TestEndpointRequest { input TestEndpointRequest {
endpoint: String! endpoint: String!
event_name: String! event_name: String!
event_description: String
headers: Map headers: Map
} }
@@ -578,6 +587,7 @@ type Mutation {
revoke(params: OAuthRevokeInput!): Response! revoke(params: OAuthRevokeInput!): Response!
verify_otp(params: VerifyOTPRequest!): AuthResponse! verify_otp(params: VerifyOTPRequest!): AuthResponse!
resend_otp(params: ResendOTPRequest!): Response! resend_otp(params: ResendOTPRequest!): Response!
deactivate_account: Response!
# admin only apis # admin only apis
_delete_user(params: DeleteUserInput!): Response! _delete_user(params: DeleteUserInput!): Response!
_update_user(params: UpdateUserInput!): User! _update_user(params: UpdateUserInput!): User!

View File

@@ -5,6 +5,7 @@ package graph
import ( import (
"context" "context"
"fmt"
"github.com/authorizerdev/authorizer/server/graph/generated" "github.com/authorizerdev/authorizer/server/graph/generated"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
@@ -81,6 +82,11 @@ func (r *mutationResolver) ResendOtp(ctx context.Context, params model.ResendOTP
return resolvers.ResendOTPResolver(ctx, params) return resolvers.ResendOTPResolver(ctx, params)
} }
// DeactivateAccount is the resolver for the deactivate_account field.
func (r *mutationResolver) DeactivateAccount(ctx context.Context) (*model.Response, error) {
panic(fmt.Errorf("not implemented: DeactivateAccount - deactivate_account"))
}
// DeleteUser is the resolver for the _delete_user field. // DeleteUser is the resolver for the _delete_user field.
func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) { func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
return resolvers.DeleteUserResolver(ctx, params) return resolvers.DeleteUserResolver(ctx, params)

View File

@@ -32,11 +32,11 @@ func OAuthCallbackHandler() gin.HandlerFunc {
return func(ctx *gin.Context) { return func(ctx *gin.Context) {
provider := ctx.Param("oauth_provider") provider := ctx.Param("oauth_provider")
state := ctx.Request.FormValue("state") state := ctx.Request.FormValue("state")
sessionState, err := memorystore.Provider.GetState(state) sessionState, err := memorystore.Provider.GetState(state)
if sessionState == "" || err != nil { if sessionState == "" || err != nil {
log.Debug("Invalid oauth state: ", state) log.Debug("Invalid oauth state: ", state)
ctx.JSON(400, gin.H{"error": "invalid oauth state"}) ctx.JSON(400, gin.H{"error": "invalid oauth state"})
return
} }
// contains random token, redirect url, role // contains random token, redirect url, role
sessionSplit := strings.Split(state, "___") sessionSplit := strings.Split(state, "___")
@@ -46,32 +46,34 @@ func OAuthCallbackHandler() gin.HandlerFunc {
ctx.JSON(400, gin.H{"error": "invalid redirect url"}) ctx.JSON(400, gin.H{"error": "invalid redirect url"})
return return
} }
// remove state from store // remove state from store
go memorystore.Provider.RemoveState(state) go memorystore.Provider.RemoveState(state)
stateValue := sessionSplit[0] stateValue := sessionSplit[0]
redirectURL := sessionSplit[1] redirectURL := sessionSplit[1]
inputRoles := strings.Split(sessionSplit[2], ",") inputRoles := strings.Split(sessionSplit[2], ",")
scopes := strings.Split(sessionSplit[3], ",") scopes := strings.Split(sessionSplit[3], ",")
var user *models.User var user *models.User
oauthCode := ctx.Request.FormValue("code") oauthCode := ctx.Request.FormValue("code")
if oauthCode == "" {
log.Debug("Invalid oauth code: ", oauthCode)
ctx.JSON(400, gin.H{"error": "invalid oauth code"})
return
}
switch provider { switch provider {
case constants.AuthRecipeMethodGoogle: case constants.AuthRecipeMethodGoogle:
user, err = processGoogleUserInfo(oauthCode) user, err = processGoogleUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodGithub: case constants.AuthRecipeMethodGithub:
user, err = processGithubUserInfo(oauthCode) user, err = processGithubUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodFacebook: case constants.AuthRecipeMethodFacebook:
user, err = processFacebookUserInfo(oauthCode) user, err = processFacebookUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodLinkedIn: case constants.AuthRecipeMethodLinkedIn:
user, err = processLinkedInUserInfo(oauthCode) user, err = processLinkedInUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodApple: case constants.AuthRecipeMethodApple:
user, err = processAppleUserInfo(oauthCode) user, err = processAppleUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodTwitter: case constants.AuthRecipeMethodTwitter:
user, err = processTwitterUserInfo(oauthCode, sessionState) user, err = processTwitterUserInfo(ctx, oauthCode, sessionState)
case constants.AuthRecipeMethodMicrosoft: case constants.AuthRecipeMethodMicrosoft:
user, err = processMicrosoftUserInfo(oauthCode) user, err = processMicrosoftUserInfo(ctx, oauthCode)
default: default:
log.Info("Invalid oauth provider") log.Info("Invalid oauth provider")
err = fmt.Errorf(`invalid oauth provider`) err = fmt.Errorf(`invalid oauth provider`)
@@ -260,6 +262,8 @@ func OAuthCallbackHandler() gin.HandlerFunc {
go func() { go func() {
if isSignUp { if isSignUp {
utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, provider, user) utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, provider, user)
// User is also logged in with signup
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user)
} else { } else {
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user) utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user)
} }
@@ -279,9 +283,8 @@ func OAuthCallbackHandler() gin.HandlerFunc {
} }
} }
func processGoogleUserInfo(code string) (*models.User, error) { func processGoogleUserInfo(ctx context.Context, code string) (*models.User, error) {
var user *models.User var user *models.User
ctx := context.Background()
oauth2Token, err := oauth.OAuthProviders.GoogleConfig.Exchange(ctx, code) oauth2Token, err := oauth.OAuthProviders.GoogleConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
@@ -311,9 +314,9 @@ func processGoogleUserInfo(code string) (*models.User, error) {
return user, nil return user, nil
} }
func processGithubUserInfo(code string) (*models.User, error) { func processGithubUserInfo(ctx context.Context, code string) (*models.User, error) {
var user *models.User var user *models.User
oauth2Token, err := oauth.OAuthProviders.GithubConfig.Exchange(context.TODO(), code) oauth2Token, err := oauth.OAuthProviders.GithubConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid github exchange code: %s", err.Error()) return user, fmt.Errorf("invalid github exchange code: %s", err.Error())
@@ -418,9 +421,9 @@ func processGithubUserInfo(code string) (*models.User, error) {
return user, nil return user, nil
} }
func processFacebookUserInfo(code string) (*models.User, error) { func processFacebookUserInfo(ctx context.Context, code string) (*models.User, error) {
var user *models.User var user *models.User
oauth2Token, err := oauth.OAuthProviders.FacebookConfig.Exchange(context.TODO(), code) oauth2Token, err := oauth.OAuthProviders.FacebookConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Invalid facebook exchange code: ", err) log.Debug("Invalid facebook exchange code: ", err)
return user, fmt.Errorf("invalid facebook exchange code: %s", err.Error()) return user, fmt.Errorf("invalid facebook exchange code: %s", err.Error())
@@ -469,9 +472,9 @@ func processFacebookUserInfo(code string) (*models.User, error) {
return user, nil return user, nil
} }
func processLinkedInUserInfo(code string) (*models.User, error) { func processLinkedInUserInfo(ctx context.Context, code string) (*models.User, error) {
var user *models.User var user *models.User
oauth2Token, err := oauth.OAuthProviders.LinkedInConfig.Exchange(context.TODO(), code) oauth2Token, err := oauth.OAuthProviders.LinkedInConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid linkedin exchange code: %s", err.Error()) return user, fmt.Errorf("invalid linkedin exchange code: %s", err.Error())
@@ -551,9 +554,9 @@ func processLinkedInUserInfo(code string) (*models.User, error) {
return user, nil return user, nil
} }
func processAppleUserInfo(code string) (*models.User, error) { func processAppleUserInfo(ctx context.Context, code string) (*models.User, error) {
var user *models.User var user *models.User
oauth2Token, err := oauth.OAuthProviders.AppleConfig.Exchange(context.TODO(), code) oauth2Token, err := oauth.OAuthProviders.AppleConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid apple exchange code: %s", err.Error()) return user, fmt.Errorf("invalid apple exchange code: %s", err.Error())
@@ -604,9 +607,9 @@ func processAppleUserInfo(code string) (*models.User, error) {
return user, err return user, err
} }
func processTwitterUserInfo(code, verifier string) (*models.User, error) { func processTwitterUserInfo(ctx context.Context, code, verifier string) (*models.User, error) {
var user *models.User var user *models.User
oauth2Token, err := oauth.OAuthProviders.TwitterConfig.Exchange(context.TODO(), code, oauth2.SetAuthURLParam("code_verifier", verifier)) oauth2Token, err := oauth.OAuthProviders.TwitterConfig.Exchange(ctx, code, oauth2.SetAuthURLParam("code_verifier", verifier))
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid twitter exchange code: %s", err.Error()) return user, fmt.Errorf("invalid twitter exchange code: %s", err.Error())
@@ -672,24 +675,24 @@ func processTwitterUserInfo(code, verifier string) (*models.User, error) {
} }
// process microsoft user information // process microsoft user information
func processMicrosoftUserInfo(code string) (*models.User, error) { func processMicrosoftUserInfo(ctx context.Context, code string) (*models.User, error) {
var user *models.User var user *models.User
ctx := context.Background()
oauth2Token, err := oauth.OAuthProviders.MicrosoftConfig.Exchange(ctx, code) oauth2Token, err := oauth.OAuthProviders.MicrosoftConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid google exchange code: %s", err.Error()) return user, fmt.Errorf("invalid microsoft exchange code: %s", err.Error())
} }
// we need to skip issuer check because for common tenant it will return internal issuer which does not match
verifier := oauth.OIDCProviders.MicrosoftOIDC.Verifier(&oidc.Config{ClientID: oauth.OAuthProviders.MicrosoftConfig.ClientID}) verifier := oauth.OIDCProviders.MicrosoftOIDC.Verifier(&oidc.Config{
ClientID: oauth.OAuthProviders.MicrosoftConfig.ClientID,
SkipIssuerCheck: true,
})
// Extract the ID Token from OAuth2 token. // Extract the ID Token from OAuth2 token.
rawIDToken, ok := oauth2Token.Extra("id_token").(string) rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok { if !ok {
log.Debug("Failed to extract ID Token from OAuth2 token") log.Debug("Failed to extract ID Token from OAuth2 token")
return user, fmt.Errorf("unable to extract id_token") return user, fmt.Errorf("unable to extract id_token")
} }
// Parse and verify ID Token payload. // Parse and verify ID Token payload.
idToken, err := verifier.Verify(ctx, rawIDToken) idToken, err := verifier.Verify(ctx, rawIDToken)
if err != nil { if err != nil {

View File

@@ -1,15 +1,44 @@
package handlers package handlers
import ( import (
"net/http"
"github.com/99designs/gqlgen/graphql/playground" "github.com/99designs/gqlgen/graphql/playground"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/token"
) )
// PlaygroundHandler is the handler for the /playground route // PlaygroundHandler is the handler for the /playground route
func PlaygroundHandler() gin.HandlerFunc { func PlaygroundHandler() gin.HandlerFunc {
h := playground.Handler("GraphQL", "/graphql")
return func(c *gin.Context) { return func(c *gin.Context) {
var h http.HandlerFunc
disablePlayground, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePlayGround)
if err != nil {
log.Debug("error while getting disable playground value")
disablePlayground = false
}
// if env set to false, then check if logged in as super admin, if logged in then return graphql else 401 error
// if env set to true, then disabled the playground with 404 error
if !disablePlayground {
if token.IsSuperAdmin(c) {
h = playground.Handler("GraphQL", "/graphql")
} else {
log.Debug("not logged in as super admin")
c.JSON(http.StatusUnauthorized, gin.H{"error": "not logged in as super admin"})
return
}
} else {
log.Debug("playground is disabled")
c.JSON(http.StatusNotFound, gin.H{"error": "playground is disabled"})
return
}
h.ServeHTTP(c.Writer, c.Request) h.ServeHTTP(c.Writer, c.Request)
} }
} }

View File

@@ -175,6 +175,8 @@ func VerifyEmailHandler() gin.HandlerFunc {
go func() { go func() {
if isSignUp { if isSignUp {
utils.RegisterEvent(c, constants.UserSignUpWebhookEvent, loginMethod, user) utils.RegisterEvent(c, constants.UserSignUpWebhookEvent, loginMethod, user)
// User is also logged in with signup
utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user)
} else { } else {
utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user) utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user)
} }

View File

@@ -38,6 +38,7 @@ func InitMemStore() error {
constants.EnvKeyDisableMultiFactorAuthentication: false, constants.EnvKeyDisableMultiFactorAuthentication: false,
constants.EnvKeyAppCookieSecure: true, constants.EnvKeyAppCookieSecure: true,
constants.EnvKeyAdminCookieSecure: true, constants.EnvKeyAdminCookieSecure: true,
constants.EnvKeyDisablePlayGround: true,
} }
requiredEnvs := RequiredEnvStoreObj.GetRequiredEnv() requiredEnvs := RequiredEnvStoreObj.GetRequiredEnv()

View File

@@ -7,18 +7,20 @@ import (
) )
type provider struct { type provider struct {
mutex sync.Mutex mutex sync.Mutex
sessionStore *stores.SessionStore sessionStore *stores.SessionStore
stateStore *stores.StateStore mfasessionStore *stores.SessionStore
envStore *stores.EnvStore stateStore *stores.StateStore
envStore *stores.EnvStore
} }
// NewInMemoryStore returns a new in-memory store. // NewInMemoryStore returns a new in-memory store.
func NewInMemoryProvider() (*provider, error) { func NewInMemoryProvider() (*provider, error) {
return &provider{ return &provider{
mutex: sync.Mutex{}, mutex: sync.Mutex{},
envStore: stores.NewEnvStore(), envStore: stores.NewEnvStore(),
sessionStore: stores.NewSessionStore(), sessionStore: stores.NewSessionStore(),
stateStore: stores.NewStateStore(), mfasessionStore: stores.NewSessionStore(),
stateStore: stores.NewStateStore(),
}, nil }, nil
} }

View File

@@ -42,6 +42,27 @@ func (c *provider) DeleteSessionForNamespace(namespace string) error {
return nil return nil
} }
// SetMfaSession sets the mfa session with key and value of userId
func (c *provider) SetMfaSession(userId, key string, expiration int64) error {
c.mfasessionStore.Set(userId, key, userId, expiration)
return nil
}
// GetMfaSession returns value of given mfa session
func (c *provider) GetMfaSession(userId, key string) (string, error) {
val := c.mfasessionStore.Get(userId, key)
if val == "" {
return "", fmt.Errorf("Not found")
}
return val, nil
}
// DeleteMfaSession deletes given mfa session from in-memory store.
func (c *provider) DeleteMfaSession(userId, key string) error {
c.mfasessionStore.Remove(userId, key)
return nil
}
// SetState sets the state in the in-memory store. // SetState sets the state in the in-memory store.
func (c *provider) SetState(key, state string) error { func (c *provider) SetState(key, state string) error {
if os.Getenv("ENV") != constants.TestEnv { if os.Getenv("ENV") != constants.TestEnv {

View File

@@ -112,4 +112,15 @@ func ProviderTests(t *testing.T, p Provider) {
key, err = p.GetUserSession("auth_provider1:124", "access_token_key") key, err = p.GetUserSession("auth_provider1:124", "access_token_key")
assert.Empty(t, key) assert.Empty(t, key)
assert.Error(t, err) assert.Error(t, err)
err = p.SetMfaSession("auth_provider:123", "session123", time.Now().Add(60*time.Second).Unix())
assert.NoError(t, err)
key, err = p.GetMfaSession("auth_provider:123", "session123")
assert.NoError(t, err)
assert.Equal(t, "auth_provider:123", key)
err = p.DeleteMfaSession("auth_provider:123", "session123")
assert.NoError(t, err)
key, err = p.GetMfaSession("auth_provider:123", "session123")
assert.Error(t, err)
assert.Empty(t, key)
} }

View File

@@ -12,6 +12,12 @@ type Provider interface {
DeleteAllUserSessions(userId string) error DeleteAllUserSessions(userId string) error
// DeleteSessionForNamespace deletes the session for a given namespace // DeleteSessionForNamespace deletes the session for a given namespace
DeleteSessionForNamespace(namespace string) error DeleteSessionForNamespace(namespace string) error
// SetMfaSession sets the mfa session with key and value of userId
SetMfaSession(userId, key string, expiration int64) error
// GetMfaSession returns value of given mfa session
GetMfaSession(userId, key string) (string, error)
// DeleteMfaSession deletes given mfa session from in-memory store.
DeleteMfaSession(userId, key string) error
// SetState sets the login state (key, value form) in the session store // SetState sets the login state (key, value form) in the session store
SetState(key, state string) error SetState(key, state string) error

View File

@@ -16,6 +16,8 @@ var (
envStorePrefix = "authorizer_env" envStorePrefix = "authorizer_env"
) )
const mfaSessionPrefix = "mfa_sess_"
// SetUserSession sets the user session for given user identifier in form recipe:user_id // SetUserSession sets the user session for given user identifier in form recipe:user_id
func (c *provider) SetUserSession(userId, key, token string, expiration int64) error { func (c *provider) SetUserSession(userId, key, token string, expiration int64) error {
currentTime := time.Now() currentTime := time.Now()
@@ -91,6 +93,37 @@ func (c *provider) DeleteSessionForNamespace(namespace string) error {
return nil return nil
} }
// SetMfaSession sets the mfa session with key and value of userId
func (c *provider) SetMfaSession(userId, key string, expiration int64) error {
currentTime := time.Now()
expireTime := time.Unix(expiration, 0)
duration := expireTime.Sub(currentTime)
err := c.store.Set(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key), userId, duration).Err()
if err != nil {
log.Debug("Error saving user session to redis: ", err)
return err
}
return nil
}
// GetMfaSession returns value of given mfa session
func (c *provider) GetMfaSession(userId, key string) (string, error) {
data, err := c.store.Get(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key)).Result()
if err != nil {
return "", err
}
return data, nil
}
// DeleteMfaSession deletes given mfa session from in-memory store.
func (c *provider) DeleteMfaSession(userId, key string) error {
if err := c.store.Del(c.ctx, fmt.Sprintf("%s%s:%s", mfaSessionPrefix, userId, key)).Err(); err != nil {
log.Debug("Error deleting user session from redis: ", err)
// continue
}
return nil
}
// SetState sets the state in redis store. // SetState sets the state in redis store.
func (c *provider) SetState(key, value string) error { func (c *provider) SetState(key, value string) error {
err := c.store.Set(c.ctx, stateStorePrefix+key, value, 0).Err() err := c.store.Set(c.ctx, stateStorePrefix+key, value, 0).Err()
@@ -143,7 +176,7 @@ func (c *provider) GetEnvStore() (map[string]interface{}, error) {
return nil, err return nil, err
} }
for key, value := range data { for key, value := range data {
if key == constants.EnvKeyDisableBasicAuthentication || key == constants.EnvKeyDisableMobileBasicAuthentication || key == constants.EnvKeyDisableEmailVerification || key == constants.EnvKeyDisableLoginPage || key == constants.EnvKeyDisableMagicLinkLogin || key == constants.EnvKeyDisableRedisForEnv || key == constants.EnvKeyDisableSignUp || key == constants.EnvKeyDisableStrongPassword || key == constants.EnvKeyIsEmailServiceEnabled || key == constants.EnvKeyIsSMSServiceEnabled || key == constants.EnvKeyEnforceMultiFactorAuthentication || key == constants.EnvKeyDisableMultiFactorAuthentication || key == constants.EnvKeyAppCookieSecure || key == constants.EnvKeyAdminCookieSecure { if key == constants.EnvKeyDisableBasicAuthentication || key == constants.EnvKeyDisableMobileBasicAuthentication || key == constants.EnvKeyDisableEmailVerification || key == constants.EnvKeyDisableLoginPage || key == constants.EnvKeyDisableMagicLinkLogin || key == constants.EnvKeyDisableRedisForEnv || key == constants.EnvKeyDisableSignUp || key == constants.EnvKeyDisableStrongPassword || key == constants.EnvKeyIsEmailServiceEnabled || key == constants.EnvKeyIsSMSServiceEnabled || key == constants.EnvKeyEnforceMultiFactorAuthentication || key == constants.EnvKeyDisableMultiFactorAuthentication || key == constants.EnvKeyAppCookieSecure || key == constants.EnvKeyAdminCookieSecure || key == constants.EnvKeyDisablePlayGround {
boolValue, err := strconv.ParseBool(value) boolValue, err := strconv.ParseBool(value)
if err != nil { if err != nil {
return res, err return res, err

View File

@@ -10,11 +10,16 @@ import (
githubOAuth2 "golang.org/x/oauth2/github" githubOAuth2 "golang.org/x/oauth2/github"
linkedInOAuth2 "golang.org/x/oauth2/linkedin" linkedInOAuth2 "golang.org/x/oauth2/linkedin"
microsoftOAuth2 "golang.org/x/oauth2/microsoft" microsoftOAuth2 "golang.org/x/oauth2/microsoft"
"google.golang.org/appengine/log"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
) )
const (
microsoftCommonTenant = "common"
)
// OAuthProviders is a struct that contains reference all the OAuth providers // OAuthProviders is a struct that contains reference all the OAuth providers
type OAuthProvider struct { type OAuthProvider struct {
GoogleConfig *oauth2.Config GoogleConfig *oauth2.Config
@@ -171,12 +176,16 @@ func InitOAuth() error {
microsoftClientSecret = "" microsoftClientSecret = ""
} }
microsoftActiveDirTenantID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftActiveDirectoryTenantID) microsoftActiveDirTenantID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyMicrosoftActiveDirectoryTenantID)
if err != nil { if err != nil || microsoftActiveDirTenantID == "" {
microsoftActiveDirTenantID = "common" microsoftActiveDirTenantID = microsoftCommonTenant
} }
if microsoftClientID != "" && microsoftClientSecret != "" && microsoftActiveDirTenantID != "" { if microsoftClientID != "" && microsoftClientSecret != "" {
if microsoftActiveDirTenantID == microsoftCommonTenant {
ctx = oidc.InsecureIssuerURLContext(ctx, fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", microsoftActiveDirTenantID))
}
p, err := oidc.NewProvider(ctx, fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", microsoftActiveDirTenantID)) p, err := oidc.NewProvider(ctx, fmt.Sprintf("https://login.microsoftonline.com/%s/v2.0", microsoftActiveDirTenantID))
if err != nil { if err != nil {
log.Debugf(ctx, "Error while creating OIDC provider for Microsoft: %v", err)
return err return err
} }
OIDCProviders.MicrosoftOIDC = p OIDCProviders.MicrosoftOIDC = p

View File

@@ -0,0 +1,58 @@
package resolvers
import (
"context"
"time"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/token"
"github.com/authorizerdev/authorizer/server/utils"
log "github.com/sirupsen/logrus"
)
// DeactivateAccountResolver is the resolver for the deactivate_account field.
func DeactivateAccountResolver(ctx context.Context) (*model.Response, error) {
var res *model.Response
gc, err := utils.GinContextFromContext(ctx)
if err != nil {
log.Debug("Failed to get GinContext: ", err)
return res, err
}
accessToken, err := token.GetAccessToken(gc)
if err != nil {
log.Debug("Failed to get access token: ", err)
return res, err
}
claims, err := token.ValidateAccessToken(gc, accessToken)
if err != nil {
log.Debug("Failed to validate access token: ", err)
return res, err
}
userID := claims["sub"].(string)
log := log.WithFields(log.Fields{
"user_id": userID,
})
user, err := db.Provider.GetUserByID(ctx, userID)
if err != nil {
log.Debug("Failed to get user by id: ", err)
return res, err
}
now := time.Now().Unix()
user.RevokedTimestamp = &now
user, err = db.Provider.UpdateUser(ctx, user)
if err != nil {
log.Debug("Failed to update user: ", err)
return res, err
}
go func() {
memorystore.Provider.DeleteAllUserSessions(user.ID)
utils.RegisterEvent(ctx, constants.UserDeactivatedWebhookEvent, "", user)
}()
res = &model.Response{
Message: `user account deactivated successfully`,
}
return res, nil
}

View File

@@ -202,6 +202,7 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
res.DisableMultiFactorAuthentication = store[constants.EnvKeyDisableMultiFactorAuthentication].(bool) res.DisableMultiFactorAuthentication = store[constants.EnvKeyDisableMultiFactorAuthentication].(bool)
res.AdminCookieSecure = store[constants.EnvKeyAdminCookieSecure].(bool) res.AdminCookieSecure = store[constants.EnvKeyAdminCookieSecure].(bool)
res.AppCookieSecure = store[constants.EnvKeyAppCookieSecure].(bool) res.AppCookieSecure = store[constants.EnvKeyAppCookieSecure].(bool)
res.DisablePlayground = store[constants.EnvKeyDisablePlayGround].(bool)
return res, nil return res, nil
} }

View File

@@ -33,13 +33,13 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
return res, err return res, err
} }
isBasiAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication)
if err != nil { if err != nil {
log.Debug("Error getting basic auth disabled: ", err) log.Debug("Error getting basic auth disabled: ", err)
isBasiAuthDisabled = true isBasicAuthDisabled = true
} }
if isBasiAuthDisabled { if isBasicAuthDisabled {
log.Debug("Basic authentication is disabled.") log.Debug("Basic authentication is disabled.")
return res, fmt.Errorf(`basic authentication is disabled for this instance`) return res, fmt.Errorf(`basic authentication is disabled for this instance`)
} }
@@ -113,16 +113,25 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
// If email service is not enabled continue the process in any way // If email service is not enabled continue the process in any way
if refs.BoolValue(user.IsMultiFactorAuthEnabled) && isEmailServiceEnabled && !isMFADisabled { if refs.BoolValue(user.IsMultiFactorAuthEnabled) && isEmailServiceEnabled && !isMFADisabled {
otp := utils.GenerateOTP() otp := utils.GenerateOTP()
expires := time.Now().Add(1 * time.Minute).Unix()
otpData, err := db.Provider.UpsertOTP(ctx, &models.OTP{ otpData, err := db.Provider.UpsertOTP(ctx, &models.OTP{
Email: user.Email, Email: user.Email,
Otp: otp, Otp: otp,
ExpiresAt: time.Now().Add(1 * time.Minute).Unix(), ExpiresAt: expires,
}) })
if err != nil { if err != nil {
log.Debug("Failed to add otp: ", err) log.Debug("Failed to add otp: ", err)
return nil, err return nil, err
} }
mfaSession := uuid.NewString()
err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expires)
if err != nil {
log.Debug("Failed to add mfasession: ", err)
return nil, err
}
cookie.SetMfaSession(gc, mfaSession)
go func() { go func() {
// exec it as go routine so that we can reduce the api latency // exec it as go routine so that we can reduce the api latency
go email.SendEmail([]string{params.Email}, constants.VerificationTypeOTP, map[string]interface{}{ go email.SendEmail([]string{params.Email}, constants.VerificationTypeOTP, map[string]interface{}{
@@ -162,7 +171,6 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
if nonce == "" { if nonce == "" {
nonce = uuid.New().String() nonce = uuid.New().String()
} }
authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, code) authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, code)
if err != nil { if err != nil {
log.Debug("Failed to create auth token", err) log.Debug("Failed to create auth token", err)

View File

@@ -33,13 +33,13 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m
return res, err return res, err
} }
isBasiAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication) isBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication)
if err != nil { if err != nil {
log.Debug("Error getting mobile basic auth disabled: ", err) log.Debug("Error getting mobile basic auth disabled: ", err)
isBasiAuthDisabled = true isBasicAuthDisabled = true
} }
if isBasiAuthDisabled { if isBasicAuthDisabled {
log.Debug("Basic authentication is disabled.") log.Debug("Basic authentication is disabled.")
return res, fmt.Errorf(`phone number based basic authentication is disabled for this instance`) return res, fmt.Errorf(`phone number based basic authentication is disabled for this instance`)
} }
@@ -122,15 +122,25 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m
smsBody := strings.Builder{} smsBody := strings.Builder{}
smsBody.WriteString("Your verification code is: ") smsBody.WriteString("Your verification code is: ")
smsBody.WriteString(smsCode) smsBody.WriteString(smsCode)
expires := time.Now().Add(duration).Unix()
_, err := db.Provider.UpsertOTP(ctx, &models.OTP{ _, err := db.Provider.UpsertOTP(ctx, &models.OTP{
PhoneNumber: params.PhoneNumber, PhoneNumber: params.PhoneNumber,
Otp: smsCode, Otp: smsCode,
ExpiresAt: time.Now().Add(duration).Unix(), ExpiresAt: expires,
}) })
if err != nil { if err != nil {
log.Debug("error while upserting OTP: ", err.Error()) log.Debug("error while upserting OTP: ", err.Error())
return nil, err return nil, err
} }
mfaSession := uuid.NewString()
err = memorystore.Provider.SetMfaSession(user.ID, mfaSession, expires)
if err != nil {
log.Debug("Failed to add mfasession: ", err)
return nil, err
}
cookie.SetMfaSession(gc, mfaSession)
go func() { go func() {
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user) utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
smsproviders.SendSMS(params.PhoneNumber, smsBody.String()) smsproviders.SendSMS(params.PhoneNumber, smsBody.String())

View File

@@ -223,6 +223,7 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput)
} }
go func() { go func() {
smsproviders.SendSMS(mobile, smsBody.String()) smsproviders.SendSMS(mobile, smsBody.String())
utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
}() }()
return &model.AuthResponse{ return &model.AuthResponse{
Message: "Please check the OTP in your inbox", Message: "Please check the OTP in your inbox",
@@ -298,6 +299,8 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput)
go func() { go func() {
utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user) utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
// User is also logged in with signup
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodMobileBasicAuth, user)
db.Provider.AddSession(ctx, &models.Session{ db.Provider.AddSession(ctx, &models.Session{
UserID: user.ID, UserID: user.ID,
UserAgent: utils.GetUserAgent(gc.Request), UserAgent: utils.GetUserAgent(gc.Request),

View File

@@ -2,6 +2,8 @@ package resolvers
import ( import (
"context" "context"
"encoding/json"
"errors"
"fmt" "fmt"
"strings" "strings"
"time" "time"
@@ -171,6 +173,17 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true) user.IsMultiFactorAuthEnabled = refs.NewBoolRef(true)
} }
if params.AppData != nil {
appDataString := ""
appDataBytes, err := json.Marshal(params.AppData)
if err != nil {
log.Debug("failed to marshall source app_data: ", err)
return nil, errors.New("malformed app_data")
}
appDataString = string(appDataBytes)
user.AppData = &appDataString
}
user.SignupMethods = constants.AuthRecipeMethodBasicAuth user.SignupMethods = constants.AuthRecipeMethodBasicAuth
isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification)
if err != nil { if err != nil {
@@ -300,7 +313,10 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
} }
go func() { go func() {
utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
// User is also logged in with signup
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
db.Provider.AddSession(ctx, &models.Session{ db.Provider.AddSession(ctx, &models.Session{
UserID: user.ID, UserID: user.ID,
UserAgent: utils.GetUserAgent(gc.Request), UserAgent: utils.GetUserAgent(gc.Request),

View File

@@ -2,6 +2,7 @@ package resolvers
import ( import (
"context" "context"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"strings" "strings"
@@ -47,7 +48,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
} }
// validate if all params are not empty // validate if all params are not empty
if params.GivenName == nil && params.FamilyName == nil && params.Picture == nil && params.MiddleName == nil && params.Nickname == nil && params.OldPassword == nil && params.Email == nil && params.Birthdate == nil && params.Gender == nil && params.PhoneNumber == nil && params.NewPassword == nil && params.ConfirmNewPassword == nil && params.IsMultiFactorAuthEnabled == nil { if params.GivenName == nil && params.FamilyName == nil && params.Picture == nil && params.MiddleName == nil && params.Nickname == nil && params.OldPassword == nil && params.Email == nil && params.Birthdate == nil && params.Gender == nil && params.PhoneNumber == nil && params.NewPassword == nil && params.ConfirmNewPassword == nil && params.IsMultiFactorAuthEnabled == nil && params.AppData == nil {
log.Debug("All params are empty") log.Debug("All params are empty")
return res, fmt.Errorf("please enter at least one param to update") return res, fmt.Errorf("please enter at least one param to update")
} }
@@ -56,7 +57,6 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
log := log.WithFields(log.Fields{ log := log.WithFields(log.Fields{
"user_id": userID, "user_id": userID,
}) })
user, err := db.Provider.GetUserByID(ctx, userID) user, err := db.Provider.GetUserByID(ctx, userID)
if err != nil { if err != nil {
log.Debug("Failed to get user by id: ", err) log.Debug("Failed to get user by id: ", err)
@@ -99,7 +99,16 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
if params.Picture != nil && refs.StringValue(user.Picture) != refs.StringValue(params.Picture) { if params.Picture != nil && refs.StringValue(user.Picture) != refs.StringValue(params.Picture) {
user.Picture = params.Picture user.Picture = params.Picture
} }
if params.AppData != nil {
appDataString := ""
appDataBytes, err := json.Marshal(params.AppData)
if err != nil {
log.Debug("failed to marshall source app_data: ", err)
return nil, errors.New("malformed app_data")
}
appDataString = string(appDataBytes)
user.AppData = &appDataString
}
if params.IsMultiFactorAuthEnabled != nil && refs.BoolValue(user.IsMultiFactorAuthEnabled) != refs.BoolValue(params.IsMultiFactorAuthEnabled) { if params.IsMultiFactorAuthEnabled != nil && refs.BoolValue(user.IsMultiFactorAuthEnabled) != refs.BoolValue(params.IsMultiFactorAuthEnabled) {
if refs.BoolValue(params.IsMultiFactorAuthEnabled) { if refs.BoolValue(params.IsMultiFactorAuthEnabled) {
isEnvServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled) isEnvServiceEnabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyIsEmailServiceEnabled)

View File

@@ -2,6 +2,7 @@ package resolvers
import ( import (
"context" "context"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"strings" "strings"
@@ -95,6 +96,17 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
user.Picture = params.Picture user.Picture = params.Picture
} }
if params.AppData != nil {
appDataString := ""
appDataBytes, err := json.Marshal(params.AppData)
if err != nil {
log.Debug("failed to marshall source app_data: ", err)
return nil, errors.New("malformed app_data")
}
appDataString = string(appDataBytes)
user.AppData = &appDataString
}
if params.IsMultiFactorAuthEnabled != nil && refs.BoolValue(user.IsMultiFactorAuthEnabled) != refs.BoolValue(params.IsMultiFactorAuthEnabled) { if params.IsMultiFactorAuthEnabled != nil && refs.BoolValue(user.IsMultiFactorAuthEnabled) != refs.BoolValue(params.IsMultiFactorAuthEnabled) {
user.IsMultiFactorAuthEnabled = params.IsMultiFactorAuthEnabled user.IsMultiFactorAuthEnabled = params.IsMultiFactorAuthEnabled
if refs.BoolValue(params.IsMultiFactorAuthEnabled) { if refs.BoolValue(params.IsMultiFactorAuthEnabled) {

View File

@@ -37,8 +37,9 @@ func ValidateSessionResolver(ctx context.Context, params *model.ValidateSessionI
log := log.WithFields(log.Fields{ log := log.WithFields(log.Fields{
"user_id": userID, "user_id": userID,
}) })
_, err = db.Provider.GetUserByID(ctx, userID) user, err := db.Provider.GetUserByID(ctx, userID)
if err != nil { if err != nil {
log.Debug("Failed to get user: ", err)
return nil, err return nil, err
} }
// refresh token has "roles" as claim // refresh token has "roles" as claim
@@ -55,5 +56,6 @@ func ValidateSessionResolver(ctx context.Context, params *model.ValidateSessionI
} }
return &model.ValidateSessionResponse{ return &model.ValidateSessionResponse{
IsValid: true, IsValid: true,
User: user.AsAPIUser(),
}, nil }, nil
} }

View File

@@ -125,6 +125,8 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
go func() { go func() {
if isSignUp { if isSignUp {
utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, loginMethod, user) utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, loginMethod, user)
// User is also logged in with signup
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
} else { } else {
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user) utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
} }

View File

@@ -27,6 +27,13 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod
log.Debug("Failed to get GinContext: ", err) log.Debug("Failed to get GinContext: ", err)
return res, err return res, err
} }
mfaSession, err := cookie.GetMfaSession(gc)
if err != nil {
log.Debug("Failed to get otp request by email: ", err)
return res, fmt.Errorf(`invalid session: %s`, err.Error())
}
if refs.StringValue(params.Email) == "" && refs.StringValue(params.PhoneNumber) == "" { if refs.StringValue(params.Email) == "" && refs.StringValue(params.PhoneNumber) == "" {
log.Debug("Email or phone number is required") log.Debug("Email or phone number is required")
return res, fmt.Errorf(`email or phone_number is required`) return res, fmt.Errorf(`email or phone_number is required`)
@@ -62,10 +69,15 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod
user, err = db.Provider.GetUserByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber)) user, err = db.Provider.GetUserByPhoneNumber(ctx, refs.StringValue(params.PhoneNumber))
} }
if user == nil || err != nil { if user == nil || err != nil {
fmt.Println("=> failing here....", err)
log.Debug("Failed to get user by email or phone number: ", err) log.Debug("Failed to get user by email or phone number: ", err)
return res, err return res, err
} }
if _, err := memorystore.Provider.GetMfaSession(user.ID, mfaSession); err != nil {
log.Debug("Failed to get mfa session: ", err)
return res, fmt.Errorf(`invalid session: %s`, err.Error())
}
isSignUp := user.EmailVerifiedAt == nil && user.PhoneNumberVerifiedAt == nil isSignUp := user.EmailVerifiedAt == nil && user.PhoneNumberVerifiedAt == nil
// TODO - Add Login method in DB when we introduce OTP for social media login // TODO - Add Login method in DB when we introduce OTP for social media login
loginMethod := constants.AuthRecipeMethodBasicAuth loginMethod := constants.AuthRecipeMethodBasicAuth
@@ -112,6 +124,8 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod
db.Provider.DeleteOTP(gc, otp) db.Provider.DeleteOTP(gc, otp)
if isSignUp { if isSignUp {
utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, loginMethod, user) utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, loginMethod, user)
// User is also logged in with signup
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
} else { } else {
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user) utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, loginMethod, user)
} }

View File

@@ -0,0 +1,45 @@
package test
import (
"context"
"testing"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert"
)
func deactivateAccountTests(t *testing.T, s TestSetup) {
t.Helper()
t.Run(`should deactiavte the user account with access token only`, func(t *testing.T) {
req, ctx := createContext(s)
email := "deactiavte_account." + s.TestInfo.Email
resolvers.SignupResolver(ctx, model.SignUpInput{
Email: email,
Password: s.TestInfo.Password,
ConfirmPassword: s.TestInfo.Password,
})
_, err := resolvers.DeactivateAccountResolver(ctx)
assert.NotNil(t, err, "unauthorized")
verificationRequest, err := db.Provider.GetVerificationRequestByEmail(ctx, email, constants.VerificationTypeBasicAuthSignup)
assert.NoError(t, err)
assert.NotNil(t, verificationRequest)
verifyRes, err := resolvers.VerifyEmailResolver(ctx, model.VerifyEmailInput{
Token: verificationRequest.Token,
})
assert.NoError(t, err)
assert.NotNil(t, verifyRes)
s.GinContext.Request.Header.Set("Authorization", "Bearer "+*verifyRes.AccessToken)
ctx = context.WithValue(req.Context(), "GinContextKey", s.GinContext)
_, err = resolvers.DeactivateAccountResolver(ctx)
assert.NoError(t, err)
s.GinContext.Request.Header.Set("Authorization", "")
assert.Nil(t, err)
_, err = resolvers.ProfileResolver(ctx)
assert.NotNil(t, err, "unauthorized")
cleanData(email)
})
}

View File

@@ -143,6 +143,7 @@ func TestResolvers(t *testing.T) {
verifyOTPTest(t, s) verifyOTPTest(t, s)
resendOTPTest(t, s) resendOTPTest(t, s)
validateSessionTests(t, s) validateSessionTests(t, s)
deactivateAccountTests(t, s)
updateAllUsersTest(t, s) updateAllUsersTest(t, s)
webhookLogsTest(t, s) // get logs after above resolver tests are done webhookLogsTest(t, s) // get logs after above resolver tests are done

View File

@@ -1,12 +1,18 @@
package test package test
import ( import (
"fmt"
"strings"
"testing" "testing"
"time"
"github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
"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/refs" "github.com/authorizerdev/authorizer/server/refs"
"github.com/authorizerdev/authorizer/server/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/google/uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -48,6 +54,17 @@ func mobileLoginTests(t *testing.T, s TestSetup) {
smsRequest, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) smsRequest, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotEmpty(t, smsRequest.Otp) assert.NotEmpty(t, smsRequest.Otp)
// Get user by phone number
user, err := db.Provider.GetUserByPhoneNumber(ctx, phoneNumber)
assert.NoError(t, err)
assert.NotNil(t, user)
// Set mfa cookie session
mfaSession := uuid.NewString()
memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
cookie = strings.TrimSuffix(cookie, ";")
req, ctx := createContext(s)
req.Header.Set("Cookie", cookie)
verifySMSRequest, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ verifySMSRequest, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
PhoneNumber: &phoneNumber, PhoneNumber: &phoneNumber,
Otp: smsRequest.Otp, Otp: smsRequest.Otp,

View File

@@ -1,7 +1,10 @@
package test package test
import ( import (
"fmt"
"strings"
"testing" "testing"
"time"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
@@ -9,6 +12,7 @@ import (
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/refs" "github.com/authorizerdev/authorizer/server/refs"
"github.com/authorizerdev/authorizer/server/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/google/uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -79,6 +83,17 @@ func mobileSingupTest(t *testing.T, s TestSetup) {
otp, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber) otp, err := db.Provider.GetOTPByPhoneNumber(ctx, phoneNumber)
assert.Nil(t, err) assert.Nil(t, err)
assert.NotEmpty(t, otp.Otp) assert.NotEmpty(t, otp.Otp)
// Get user by phone number
user, err := db.Provider.GetUserByPhoneNumber(ctx, phoneNumber)
assert.NoError(t, err)
assert.NotNil(t, user)
// Set mfa cookie session
mfaSession := uuid.NewString()
memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
cookie = strings.TrimSuffix(cookie, ";")
req, ctx := createContext(s)
req.Header.Set("Cookie", cookie)
otpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ otpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
PhoneNumber: &phoneNumber, PhoneNumber: &phoneNumber,
Otp: otp.Otp, Otp: otp.Otp,

View File

@@ -2,13 +2,18 @@ package test
import ( import (
"context" "context"
"fmt"
"strings"
"testing" "testing"
"time"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
"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/refs" "github.com/authorizerdev/authorizer/server/refs"
"github.com/authorizerdev/authorizer/server/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/google/uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -89,6 +94,16 @@ func resendOTPTest(t *testing.T, s TestSetup) {
}) })
assert.Error(t, err) assert.Error(t, err)
assert.Nil(t, verifyOtpRes) assert.Nil(t, verifyOtpRes)
// Get user by email
user, err := db.Provider.GetUserByEmail(ctx, email)
assert.NoError(t, err)
assert.NotNil(t, user)
// Set mfa cookie session
mfaSession := uuid.NewString()
memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
cookie = strings.TrimSuffix(cookie, ";")
req.Header.Set("Cookie", cookie)
verifyOtpRes, err = resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ verifyOtpRes, err = resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
Email: &email, Email: &email,
Otp: newOtp.Otp, Otp: newOtp.Otp,

View File

@@ -103,7 +103,7 @@ func testSetup() TestSetup {
Email: fmt.Sprintf("%d_authorizer_tester@yopmail.com", time.Now().Unix()), Email: fmt.Sprintf("%d_authorizer_tester@yopmail.com", time.Now().Unix()),
Password: "Test@123", Password: "Test@123",
WebhookEndpoint: "https://62f93101e05644803533cf36.mockapi.io/authorizer/webhook", WebhookEndpoint: "https://62f93101e05644803533cf36.mockapi.io/authorizer/webhook",
TestWebhookEventTypes: []string{constants.UserAccessEnabledWebhookEvent, constants.UserAccessRevokedWebhookEvent, constants.UserCreatedWebhookEvent, constants.UserDeletedWebhookEvent, constants.UserLoginWebhookEvent, constants.UserSignUpWebhookEvent}, TestWebhookEventTypes: []string{constants.UserAccessEnabledWebhookEvent, constants.UserAccessRevokedWebhookEvent, constants.UserCreatedWebhookEvent, constants.UserDeletedWebhookEvent, constants.UserLoginWebhookEvent, constants.UserSignUpWebhookEvent, constants.UserDeactivatedWebhookEvent},
TestEmailTemplateEventTypes: []string{constants.VerificationTypeBasicAuthSignup, constants.VerificationTypeForgotPassword, constants.VerificationTypeMagicLinkLogin, constants.VerificationTypeUpdateEmail}, TestEmailTemplateEventTypes: []string{constants.VerificationTypeBasicAuthSignup, constants.VerificationTypeForgotPassword, constants.VerificationTypeMagicLinkLogin, constants.VerificationTypeUpdateEmail},
} }

View File

@@ -56,6 +56,7 @@ func validateSessionTests(t *testing.T, s TestSetup) {
res, err = resolvers.ValidateSessionResolver(ctx, &model.ValidateSessionInput{}) res, err = resolvers.ValidateSessionResolver(ctx, &model.ValidateSessionInput{})
assert.Nil(t, err) assert.Nil(t, err)
assert.True(t, res.IsValid) assert.True(t, res.IsValid)
assert.Equal(t, res.User.ID, verifyRes.User.ID)
cleanData(email) cleanData(email)
}) })
} }

View File

@@ -2,13 +2,18 @@ package test
import ( import (
"context" "context"
"fmt"
"strings"
"testing" "testing"
"time"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/db" "github.com/authorizerdev/authorizer/server/db"
"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/refs" "github.com/authorizerdev/authorizer/server/refs"
"github.com/authorizerdev/authorizer/server/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/google/uuid"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -63,7 +68,16 @@ func verifyOTPTest(t *testing.T, s TestSetup) {
otp, err := db.Provider.GetOTPByEmail(ctx, email) otp, err := db.Provider.GetOTPByEmail(ctx, email)
assert.NoError(t, err) assert.NoError(t, err)
assert.NotEmpty(t, otp.Otp) assert.NotEmpty(t, otp.Otp)
// Get user by email
user, err := db.Provider.GetUserByEmail(ctx, email)
assert.NoError(t, err)
assert.NotNil(t, user)
// Set mfa cookie session
mfaSession := uuid.NewString()
memorystore.Provider.SetMfaSession(user.ID, mfaSession, time.Now().Add(1*time.Minute).Unix())
cookie := fmt.Sprintf("%s=%s;", constants.MfaCookieName+"_session", mfaSession)
cookie = strings.TrimSuffix(cookie, ";")
req.Header.Set("Cookie", cookie)
verifyOtpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{ verifyOtpRes, err := resolvers.VerifyOtpResolver(ctx, model.VerifyOTPRequest{
Email: &email, Email: &email,
Otp: otp.Otp, Otp: otp.Otp,

View File

@@ -83,10 +83,8 @@ func RegisterEvent(ctx context.Context, eventName string, authRecipe string, use
} }
req.Header.Set("Content-Type", "application/json") req.Header.Set("Content-Type", "application/json")
if webhook.Headers != nil { for key, val := range webhook.Headers {
for key, val := range webhook.Headers { req.Header.Set(key, val.(string))
req.Header.Set(key, val.(string))
}
} }
client := &http.Client{Timeout: time.Second * 30} client := &http.Client{Timeout: time.Second * 30}

View File

@@ -4,7 +4,7 @@ import "github.com/authorizerdev/authorizer/server/constants"
// IsValidWebhookEventName to validate webhook event name // IsValidWebhookEventName to validate webhook event name
func IsValidWebhookEventName(eventName string) bool { func IsValidWebhookEventName(eventName string) bool {
if eventName != constants.UserCreatedWebhookEvent && eventName != constants.UserLoginWebhookEvent && eventName != constants.UserSignUpWebhookEvent && eventName != constants.UserDeletedWebhookEvent && eventName != constants.UserAccessEnabledWebhookEvent && eventName != constants.UserAccessRevokedWebhookEvent { if eventName != constants.UserCreatedWebhookEvent && eventName != constants.UserLoginWebhookEvent && eventName != constants.UserSignUpWebhookEvent && eventName != constants.UserDeletedWebhookEvent && eventName != constants.UserAccessEnabledWebhookEvent && eventName != constants.UserAccessRevokedWebhookEvent && eventName != constants.UserDeactivatedWebhookEvent {
return false return false
} }