Compare commits

...

36 Commits

Author SHA1 Message Date
Lakhan Samani
6c9b359081 Merge pull request #355 from minilikmila/fix/facebook-login
Modify the Facebook login authentication callback to enable user email access through the response body.
2023-05-29 10:32:27 +05:30
Mila Shumete
0fde46d274 setting on facebook user email method --- change the parameter(key) passed to get the email from map 2023-05-28 17:10:29 +03:00
Lakhan Samani
1a5b446894 Merge pull request #353 from authorizerdev/add-get-user-by-email
[server] add ability to get user by email
2023-05-20 09:50:59 +05:30
Lakhan Samani
930c934fdb [server] add ability to get user by email 2023-05-20 09:49:18 +05:30
Lakhan Samani
4e7074d75b Merge pull request #351 from miqe/feat/add_sender_name
Feat/add sender name
2023-05-16 14:07:18 +05:30
Michael Sahlu
bdfa045a43 add SENDER_NAME env 2023-05-16 00:59:45 +03:00
Michael Sahlu
a258399bde add Sender Name input 2023-05-16 00:59:01 +03:00
Michael Sahlu
55a25436a8 add SENDER_NAME in env variable query 2023-05-16 00:58:26 +03:00
Michael Sahlu
9fa402f5c8 add SENDER_NAME environment and types 2023-05-16 00:57:33 +03:00
Michael Sahlu
1111729ad4 add sender name / from name 2023-05-16 00:51:28 +03:00
Michael Sahlu
e56c2f58e5 add sender name on schema and resolver 2023-05-16 00:46:22 +03:00
Michael Sahlu
8dbd2556eb retrive sender name from env 2023-05-16 00:40:14 +03:00
Michael Sahlu
17bb077f3e add EnvKeySenderName for SENDER_NAME env variable 2023-05-16 00:39:25 +03:00
Lakhan Samani
f291417378 Merge pull request #350 from authorizerdev/fix/redirect-uri-error
[server]fix: error redirection for email verification
2023-05-12 16:43:38 +05:30
Lakhan Samani
f831379d27 revert change for forgot password 2023-05-12 16:39:02 +05:30
Lakhan Samani
a50f6becbd [server]fix: error redirection for email verification 2023-05-02 18:39:10 +05:30
Lakhan Samani
a6f6e0b18a Merge pull request #349 from darshvaghela/main 2023-04-24 09:32:38 +05:30
darshvaghela
3868157e11 refactored code 2023-04-23 17:31:24 +05:30
darshvaghela
d693c05483 Features enhancement (Disable/Enable) 2023-04-22 15:21:47 +05:30
Lakhan Samani
6f1fbf886d Merge pull request #346 from MussieT/feat/return-user-info-on-invitation
Feat/return user info on invitation
2023-04-20 13:59:49 +05:30
Mussie Teshome
b86487fda4 assert message and response is not null 2023-04-20 10:43:06 +03:00
Mussie Teshome
28d4ddeb50 Return the new emails only 2023-04-19 15:38:30 +03:00
Mussie Teshome
b9ab1d3761 return err on err 2023-04-19 15:31:57 +03:00
Mussie Teshome
a5b643e127 removed unnecessary comment 2023-04-19 15:19:17 +03:00
Mussie Teshome
691664e629 Invite members resolver updated to return user info 2023-04-19 14:46:27 +03:00
Mussie Teshome
efb67a9538 New response type for invite members 2023-04-19 14:45:22 +03:00
Mussie Teshome
a0f2eeba3e golang package updates 2023-04-19 14:44:50 +03:00
Mussie Teshome
d1a0ccd790 package updates while running make clean && make 2023-04-19 14:44:17 +03:00
Lakhan Samani
729c23f578 [chore]: update authorizer-react 2023-04-15 14:14:47 +05:30
Lakhan Samani
a074f85391 [chore]: update contributing guide 2023-04-15 08:33:33 +05:30
Lakhan Samani
4e7ec6cb7b [chore]: add command to generate db template 2023-04-15 08:13:10 +05:30
Lakhan Samani
6d541cbfb9 fix: use normal mutex for cache 2023-04-10 15:33:59 +05:30
Lakhan Samani
1ebba7f2b7 Merge pull request #343 from authorizerdev/fix/session-storage
fix: session storage
2023-04-08 18:07:52 +05:30
Lakhan Samani
428a0be3db feat: add cache clear 2023-04-08 18:02:53 +05:30
Lakhan Samani
02c0ebb9c4 fix: session storage 2023-04-08 13:06:15 +05:30
Lakhan Samani
9a284c03ca fix: redis session 2023-04-03 10:26:27 +05:30
58 changed files with 4035 additions and 2053 deletions

View File

@@ -7,4 +7,5 @@ SMTP_PORT=2525
SMTP_USERNAME=test SMTP_USERNAME=test
SMTP_PASSWORD=test SMTP_PASSWORD=test
SENDER_EMAIL="info@authorizer.dev" SENDER_EMAIL="info@authorizer.dev"
SENDER_NAME="Authorizer"
AWS_REGION=ap-south-1 AWS_REGION=ap-south-1

View File

@@ -45,12 +45,30 @@ Please ask as many questions as you need, either directly in the issue or on [Di
1. Fork the [authorizer](https://github.com/authorizerdev/authorizer) repository (**Skip this step if you have access to repo**) 1. Fork the [authorizer](https://github.com/authorizerdev/authorizer) repository (**Skip this step if you have access to repo**)
2. Clone repo: `git clone https://github.com/authorizerdev/authorizer.git` or use the forked url from step 1 2. Clone repo: `git clone https://github.com/authorizerdev/authorizer.git` or use the forked url from step 1
3. Change directory to authorizer: `cd authorizer` 3. Change directory to authorizer: `cd authorizer`
5. Create Env file `cp .env.sample .env`. Check all the supported env [here](https://docs.authorizer.dev/core/env/) 4. Create Env file `cp .env.sample .env`. Check all the supported env [here](https://docs.authorizer.dev/core/env/)
6. Build Dashboard `make build-dashboard` 5. Build Dashboard `make build-dashboard`
7. Build App `make build-app` 6. Build App `make build-app`
8. Build Server `make clean && make` 7. Build Server `make clean && make`
> Note: if you don't have [`make`](https://www.ibm.com/docs/en/aix/7.2?topic=concepts-make-command), you can `cd` into `server` dir and build using the `go build` command. In that case you will have to build `dashboard` & `app` manually using `npm run build` on both dirs. > Note: if you don't have [`make`](https://www.ibm.com/docs/en/aix/7.2?topic=concepts-make-command), you can `cd` into `server` dir and build using the `go build` command. In that case you will have to build `dashboard` & `app` manually using `npm run build` on both dirs.
9. Run binary `./build/server` 8. Run binary `./build/server`
### Updating GraphQL schema
- Modify `server/graph/schema.graphqls` file
- Run `make generate-graphql` this will update the models and required methods
- If a new mutation or query is added
- Write the implementation for the new resolver in `server/resolvers/NEW_RESOLVER.GO`
- Update `server/graph/schema.resolvers.go` with the new resolver method
### Adding support for new database
- Run `make generate-db-template dbname=NEW_DB_NAME`
eg `make generate-db-template dbname=dynamodb`
This command will generate a folder in server/db/providers/ with name specified in the above command.
One will have to implement methods present in that folder.
> Note: Connection for database and schema changes are written in `server/db/providers/DB_NAME/provider.go` > `NewProvider` method is called for any given db based on the env variables present.
### Testing ### Testing

View File

@@ -52,5 +52,8 @@ test-all-db:
docker rm -vf authorizer_arangodb docker rm -vf authorizer_arangodb
docker rm -vf dynamodb-local-test docker rm -vf dynamodb-local-test
docker rm -vf couchbase-local-test docker rm -vf couchbase-local-test
generate: generate-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:
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' {} \;

35
app/package-lock.json generated
View File

@@ -9,7 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@authorizerdev/authorizer-react": "^1.1.8", "@authorizerdev/authorizer-react": "^1.1.11",
"@types/react": "^17.0.15", "@types/react": "^17.0.15",
"@types/react-dom": "^17.0.9", "@types/react-dom": "^17.0.9",
"esbuild": "^0.12.17", "esbuild": "^0.12.17",
@@ -27,22 +27,25 @@
} }
}, },
"node_modules/@authorizerdev/authorizer-js": { "node_modules/@authorizerdev/authorizer-js": {
"version": "1.1.4", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.1.4.tgz", "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.3.tgz",
"integrity": "sha512-oLp3XMYU9xHlg5urpAOaw6NrKQ07SaI8oAi1BAMHZWivv5qi2V+6roey0y9MdvCUmsMULBBcZg87kuoMTXRJOw==", "integrity": "sha512-rk/fMRIsqbp+fsy2y09etVjf7CY9/4mG6hf0RKgXgRRfxtAQa1jdkt/De23hBTNeEwAWu6hP/9BQZjcrln6KtA==",
"dependencies": { "dependencies": {
"cross-fetch": "^3.1.5" "cross-fetch": "^3.1.5"
}, },
"engines": { "engines": {
"node": ">=10" "node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/authorizerdev"
} }
}, },
"node_modules/@authorizerdev/authorizer-react": { "node_modules/@authorizerdev/authorizer-react": {
"version": "1.1.8", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.8.tgz", "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.11.tgz",
"integrity": "sha512-5v9Zc7ZxiEQEHT1Fwj1jvEemdckcrn7mZPkdmJ/z0YOWNbF20ZpM4WsfrtJB+d293m7Rb1QKwzdFPkYINMh5tw==", "integrity": "sha512-tSI/yjsoeK/RvCOMiHSf1QGOeSpaLYQZEM864LFLndKoJwk7UWCJ86qg1w6ge7B00PmZSNWqST/w5JTcQaVNpw==",
"dependencies": { "dependencies": {
"@authorizerdev/authorizer-js": "^1.1.4" "@authorizerdev/authorizer-js": "^1.2.3"
}, },
"engines": { "engines": {
"node": ">=10" "node": ">=10"
@@ -834,19 +837,19 @@
}, },
"dependencies": { "dependencies": {
"@authorizerdev/authorizer-js": { "@authorizerdev/authorizer-js": {
"version": "1.1.4", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.1.4.tgz", "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.3.tgz",
"integrity": "sha512-oLp3XMYU9xHlg5urpAOaw6NrKQ07SaI8oAi1BAMHZWivv5qi2V+6roey0y9MdvCUmsMULBBcZg87kuoMTXRJOw==", "integrity": "sha512-rk/fMRIsqbp+fsy2y09etVjf7CY9/4mG6hf0RKgXgRRfxtAQa1jdkt/De23hBTNeEwAWu6hP/9BQZjcrln6KtA==",
"requires": { "requires": {
"cross-fetch": "^3.1.5" "cross-fetch": "^3.1.5"
} }
}, },
"@authorizerdev/authorizer-react": { "@authorizerdev/authorizer-react": {
"version": "1.1.8", "version": "1.1.11",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.8.tgz", "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.11.tgz",
"integrity": "sha512-5v9Zc7ZxiEQEHT1Fwj1jvEemdckcrn7mZPkdmJ/z0YOWNbF20ZpM4WsfrtJB+d293m7Rb1QKwzdFPkYINMh5tw==", "integrity": "sha512-tSI/yjsoeK/RvCOMiHSf1QGOeSpaLYQZEM864LFLndKoJwk7UWCJ86qg1w6ge7B00PmZSNWqST/w5JTcQaVNpw==",
"requires": { "requires": {
"@authorizerdev/authorizer-js": "^1.1.4" "@authorizerdev/authorizer-js": "^1.2.3"
} }
}, },
"@babel/code-frame": { "@babel/code-frame": {

View File

@@ -12,7 +12,7 @@
"author": "Lakhan Samani", "author": "Lakhan Samani",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@authorizerdev/authorizer-react": "^1.1.9", "@authorizerdev/authorizer-react": "^1.1.11",
"@types/react": "^17.0.15", "@types/react": "^17.0.15",
"@types/react-dom": "^17.0.9", "@types/react-dom": "^17.0.9",
"esbuild": "^0.12.17", "esbuild": "^0.12.17",

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -126,6 +126,22 @@ const EmailConfigurations = ({
/> />
</Center> </Center>
</Flex> </Flex>
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
<Flex w="30%" justifyContent="start" alignItems="center">
<Text fontSize="sm">Sender Name:</Text>
</Flex>
<Center
w={isNotSmallerScreen ? '70%' : '100%'}
mt={isNotSmallerScreen ? '0' : '3'}
>
<InputField
borderRadius={5}
variables={variables}
setVariables={setVariables}
inputType={TextInputType.SENDER_NAME}
/>
</Center>
</Flex>
</Stack> </Stack>
</div> </div>
); );

View File

@@ -8,86 +8,90 @@ const Features = ({ variables, setVariables }: any) => {
<div> <div>
{' '} {' '}
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}> <Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={5}>
Disable Features Features
</Text> </Text>
<Stack spacing={6}> <Stack spacing={6}>
<Flex> <Flex>
<Flex w="100%" justifyContent="start" alignItems="center"> <Flex w="100%" justifyContent="start" alignItems="center">
<Text fontSize="sm">Disable Login Page:</Text> <Text fontSize="sm">Login Page:</Text>
</Flex> </Flex>
<Flex justifyContent="start"> <Flex justifyContent="start">
<InputField <InputField
variables={variables} variables={variables}
setVariables={setVariables} setVariables={setVariables}
inputType={SwitchInputType.DISABLE_LOGIN_PAGE} inputType={SwitchInputType.DISABLE_LOGIN_PAGE}
hasReversedValue
/> />
</Flex> </Flex>
</Flex> </Flex>
<Flex> <Flex>
<Flex w="100%" justifyContent="start" alignItems="center"> <Flex w="100%" justifyContent="start" alignItems="center">
<Text fontSize="sm">Disable Email Verification:</Text> <Text fontSize="sm">Email Verification:</Text>
</Flex> </Flex>
<Flex justifyContent="start"> <Flex justifyContent="start">
<InputField <InputField
variables={variables} variables={variables}
setVariables={setVariables} setVariables={setVariables}
inputType={SwitchInputType.DISABLE_EMAIL_VERIFICATION} inputType={SwitchInputType.DISABLE_EMAIL_VERIFICATION}
hasReversedValue
/> />
</Flex> </Flex>
</Flex> </Flex>
<Flex> <Flex>
<Flex w="100%" justifyContent="start" alignItems="center"> <Flex w="100%" justifyContent="start" alignItems="center">
<Text fontSize="sm">Disable Magic Login Link:</Text> <Text fontSize="sm">Magic Login Link:</Text>
</Flex> </Flex>
<Flex justifyContent="start"> <Flex justifyContent="start">
<InputField <InputField
variables={variables} variables={variables}
setVariables={setVariables} setVariables={setVariables}
inputType={SwitchInputType.DISABLE_MAGIC_LINK_LOGIN} inputType={SwitchInputType.DISABLE_MAGIC_LINK_LOGIN}
hasReversedValue
/> />
</Flex> </Flex>
</Flex> </Flex>
<Flex> <Flex>
<Flex w="100%" justifyContent="start" alignItems="center"> <Flex w="100%" justifyContent="start" alignItems="center">
<Text fontSize="sm">Disable Basic Authentication:</Text> <Text fontSize="sm">Basic Authentication:</Text>
</Flex> </Flex>
<Flex justifyContent="start"> <Flex justifyContent="start">
<InputField <InputField
variables={variables} variables={variables}
setVariables={setVariables} setVariables={setVariables}
inputType={SwitchInputType.DISABLE_BASIC_AUTHENTICATION} inputType={SwitchInputType.DISABLE_BASIC_AUTHENTICATION}
hasReversedValue
/> />
</Flex> </Flex>
</Flex> </Flex>
<Flex> <Flex>
<Flex w="100%" justifyContent="start" alignItems="center"> <Flex w="100%" justifyContent="start" alignItems="center">
<Text fontSize="sm">Disable Sign Up:</Text> <Text fontSize="sm">Sign Up:</Text>
</Flex> </Flex>
<Flex justifyContent="start" mb={3}> <Flex justifyContent="start" mb={3}>
<InputField <InputField
variables={variables} variables={variables}
setVariables={setVariables} setVariables={setVariables}
inputType={SwitchInputType.DISABLE_SIGN_UP} inputType={SwitchInputType.DISABLE_SIGN_UP}
hasReversedValue
/> />
</Flex> </Flex>
</Flex> </Flex>
<Flex> <Flex>
<Flex w="100%" justifyContent="start" alignItems="center"> <Flex w="100%" justifyContent="start" alignItems="center">
<Text fontSize="sm">Disable Strong Password:</Text> <Text fontSize="sm">Strong Password:</Text>
</Flex> </Flex>
<Flex justifyContent="start" mb={3}> <Flex justifyContent="start" mb={3}>
<InputField <InputField
variables={variables} variables={variables}
setVariables={setVariables} setVariables={setVariables}
inputType={SwitchInputType.DISABLE_STRONG_PASSWORD} inputType={SwitchInputType.DISABLE_STRONG_PASSWORD}
hasReversedValue
/> />
</Flex> </Flex>
</Flex> </Flex>
<Flex alignItems="center"> <Flex alignItems="center">
<Flex w="100%" alignItems="baseline" flexDir="column"> <Flex w="100%" alignItems="baseline" flexDir="column">
<Text fontSize="sm"> <Text fontSize="sm">Multi Factor Authentication (MFA):</Text>
Disable Multi Factor Authentication (MFA):
</Text>
<Text fontSize="x-small"> <Text fontSize="x-small">
Note: Enabling this will ignore Enforcing MFA shown below and will Note: Enabling this will ignore Enforcing MFA shown below and will
also ignore the user MFA setting. also ignore the user MFA setting.
@@ -98,15 +102,10 @@ const Features = ({ variables, setVariables }: any) => {
variables={variables} variables={variables}
setVariables={setVariables} setVariables={setVariables}
inputType={SwitchInputType.DISABLE_MULTI_FACTOR_AUTHENTICATION} inputType={SwitchInputType.DISABLE_MULTI_FACTOR_AUTHENTICATION}
hasReversedValue
/> />
</Flex> </Flex>
</Flex> </Flex>
</Stack>
<Divider paddingY={5} />
<Text fontSize="md" paddingTop={5} fontWeight="bold" mb={5}>
Enable Features
</Text>
<Stack spacing={6}>
<Flex alignItems="center"> <Flex alignItems="center">
<Flex w="100%" alignItems="baseline" flexDir="column"> <Flex w="100%" alignItems="baseline" flexDir="column">
<Text fontSize="sm"> <Text fontSize="sm">

View File

@@ -48,6 +48,8 @@ const InputField = ({
fieldVisibility, fieldVisibility,
setFieldVisibility, setFieldVisibility,
availableRoles, availableRoles,
// This prop is added to improve the user experience for the boolean ENV variable having `DISABLE_` prefix, as those values need to be considered in inverted form.
hasReversedValue,
...downshiftProps ...downshiftProps
}: any) => { }: any) => {
const props = { const props = {
@@ -398,7 +400,9 @@ const InputField = ({
</Text> </Text>
<Switch <Switch
size="md" size="md"
isChecked={variables[inputType]} isChecked={
hasReversedValue ? !variables[inputType] : variables[inputType]
}
onChange={() => { onChange={() => {
setVariables({ setVariables({
...variables, ...variables,

View File

@@ -19,6 +19,7 @@ export const TextInputType = {
SMTP_USERNAME: 'SMTP_USERNAME', SMTP_USERNAME: 'SMTP_USERNAME',
SMTP_LOCAL_NAME: 'SMTP_LOCAL_NAME', SMTP_LOCAL_NAME: 'SMTP_LOCAL_NAME',
SENDER_EMAIL: 'SENDER_EMAIL', SENDER_EMAIL: 'SENDER_EMAIL',
SENDER_NAME: 'SENDER_NAME',
ORGANIZATION_NAME: 'ORGANIZATION_NAME', ORGANIZATION_NAME: 'ORGANIZATION_NAME',
ORGANIZATION_LOGO: 'ORGANIZATION_LOGO', ORGANIZATION_LOGO: 'ORGANIZATION_LOGO',
DATABASE_NAME: 'DATABASE_NAME', DATABASE_NAME: 'DATABASE_NAME',
@@ -143,6 +144,7 @@ export interface envVarTypes {
SMTP_PASSWORD: string; SMTP_PASSWORD: string;
SMTP_LOCAL_NAME: string; SMTP_LOCAL_NAME: string;
SENDER_EMAIL: string; SENDER_EMAIL: string;
SENDER_NAME: string;
ALLOWED_ORIGINS: [string] | []; ALLOWED_ORIGINS: [string] | [];
ORGANIZATION_NAME: string; ORGANIZATION_NAME: string;
ORGANIZATION_LOGO: string; ORGANIZATION_LOGO: string;

View File

@@ -50,6 +50,7 @@ export const EnvVariablesQuery = `
SMTP_PASSWORD SMTP_PASSWORD
SMTP_LOCAL_NAME SMTP_LOCAL_NAME
SENDER_EMAIL SENDER_EMAIL
SENDER_NAME
ALLOWED_ORIGINS ALLOWED_ORIGINS
ORGANIZATION_NAME ORGANIZATION_NAME
ORGANIZATION_LOGO ORGANIZATION_LOGO

View File

@@ -70,6 +70,7 @@ const Environment = () => {
SMTP_PASSWORD: '', SMTP_PASSWORD: '',
SMTP_LOCAL_NAME: '', SMTP_LOCAL_NAME: '',
SENDER_EMAIL: '', SENDER_EMAIL: '',
SENDER_NAME: '',
ALLOWED_ORIGINS: [], ALLOWED_ORIGINS: [],
ORGANIZATION_NAME: '', ORGANIZATION_NAME: '',
ORGANIZATION_LOGO: '', ORGANIZATION_LOGO: '',

File diff suppressed because it is too large Load Diff

View File

@@ -62,6 +62,8 @@ const (
EnvKeySmtpLocalName = "SMTP_LOCAL_NAME" EnvKeySmtpLocalName = "SMTP_LOCAL_NAME"
// EnvKeySenderEmail key for env variable SENDER_EMAIL // EnvKeySenderEmail key for env variable SENDER_EMAIL
EnvKeySenderEmail = "SENDER_EMAIL" EnvKeySenderEmail = "SENDER_EMAIL"
// EnvKeySenderName key for env variable SENDER_NAME
EnvKeySenderName = "SENDER_NAME"
// EnvKeyIsEmailServiceEnabled key for env variable IS_EMAIL_SERVICE_ENABLED // EnvKeyIsEmailServiceEnabled key for env variable IS_EMAIL_SERVICE_ENABLED
EnvKeyIsEmailServiceEnabled = "IS_EMAIL_SERVICE_ENABLED" EnvKeyIsEmailServiceEnabled = "IS_EMAIL_SERVICE_ENABLED"
// EnvKeyAppCookieSecure key for env variable APP_COOKIE_SECURE // EnvKeyAppCookieSecure key for env variable APP_COOKIE_SECURE

View File

@@ -103,6 +103,12 @@ func SendEmail(to []string, event string, data map[string]interface{}) error {
return err return err
} }
senderName, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySenderName)
if err != nil {
log.Errorf("Error while getting sender name from env variable: %v", err)
return err
}
smtpPort, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpPort) smtpPort, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeySmtpPort)
if err != nil { if err != nil {
log.Errorf("Error while getting smtp port from env variable: %v", err) log.Errorf("Error while getting smtp port from env variable: %v", err)
@@ -139,7 +145,7 @@ func SendEmail(to []string, event string, data map[string]interface{}) error {
return err return err
} }
m.SetHeader("From", senderEmail) m.SetAddressHeader("From", senderEmail, senderName)
m.SetHeader("To", to...) m.SetHeader("To", to...)
m.SetHeader("Subject", tmp.Subject) m.SetHeader("Subject", tmp.Subject)
m.SetBody("text/html", tmp.Template) m.SetBody("text/html", tmp.Template)

8
server/env/env.go vendored
View File

@@ -57,6 +57,7 @@ func InitAllEnv() error {
osSmtpPassword := os.Getenv(constants.EnvKeySmtpPassword) osSmtpPassword := os.Getenv(constants.EnvKeySmtpPassword)
osSmtpLocalName := os.Getenv(constants.EnvKeySmtpLocalName) osSmtpLocalName := os.Getenv(constants.EnvKeySmtpLocalName)
osSenderEmail := os.Getenv(constants.EnvKeySenderEmail) osSenderEmail := os.Getenv(constants.EnvKeySenderEmail)
osSenderName := os.Getenv(constants.EnvKeySenderName)
osJwtType := os.Getenv(constants.EnvKeyJwtType) osJwtType := os.Getenv(constants.EnvKeyJwtType)
osJwtSecret := os.Getenv(constants.EnvKeyJwtSecret) osJwtSecret := os.Getenv(constants.EnvKeyJwtSecret)
osJwtPrivateKey := os.Getenv(constants.EnvKeyJwtPrivateKey) osJwtPrivateKey := os.Getenv(constants.EnvKeyJwtPrivateKey)
@@ -257,6 +258,13 @@ func InitAllEnv() error {
envData[constants.EnvKeySenderEmail] = osSenderEmail envData[constants.EnvKeySenderEmail] = osSenderEmail
} }
if val, ok := envData[constants.EnvKeySenderName]; !ok || val == "" {
envData[constants.EnvKeySenderName] = osSenderName
}
if osSenderName != "" && envData[constants.EnvKeySenderName] != osSenderName {
envData[constants.EnvKeySenderName] = osSenderName
}
algoVal, ok := envData[constants.EnvKeyJwtType] algoVal, ok := envData[constants.EnvKeyJwtType]
algo := "" algo := ""
if !ok || algoVal == "" { if !ok || algoVal == "" {

View File

@@ -11,16 +11,17 @@ require (
github.com/gin-gonic/gin v1.8.1 github.com/gin-gonic/gin v1.8.1
github.com/glebarez/sqlite v1.5.0 github.com/glebarez/sqlite v1.5.0
github.com/go-playground/validator/v10 v10.11.1 // indirect github.com/go-playground/validator/v10 v10.11.1 // indirect
github.com/go-redis/redis/v8 v8.11.0
github.com/goccy/go-json v0.9.11 // indirect github.com/goccy/go-json v0.9.11 // indirect
github.com/gocql/gocql v1.2.0 github.com/gocql/gocql v1.2.0
github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.6 // indirect
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/guregu/dynamo v1.16.0 github.com/guregu/dynamo v1.16.0
github.com/joho/godotenv v1.3.0 github.com/joho/godotenv v1.3.0
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/redis/go-redis/v9 v9.0.3
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.8.0 github.com/stretchr/testify v1.8.0

View File

@@ -58,11 +58,15 @@ github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYE
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao=
github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo=
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -96,9 +100,6 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8=
@@ -119,8 +120,6 @@ github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/go-redis/redis/v8 v8.11.0 h1:O1Td0mQ8UFChQ3N9zFQqo6kTU2cJ+/it88gDB+zg0wo=
github.com/go-redis/redis/v8 v8.11.0/go.mod h1:DLomh7y2e3ggQXQLd1YgmvIfecPJoFl7WU5SOQ/r06M=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
@@ -212,7 +211,6 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
@@ -273,16 +271,6 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.15.0 h1:1V1NfVQR87RtWAgp1lv9JZJ5Jap+XFGKPi00andXGi4=
github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
@@ -295,6 +283,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/redis/go-redis/v9 v9.0.3 h1:+7mmR26M0IvyLxGZUHxu4GiBkJkVDid0Un+j4ScYu4k=
github.com/redis/go-redis/v9 v9.0.3/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f h1:a7clxaGmmqtdNTXyvrp/lVO/Gnkzlhc/+dLs5v965GM= github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f h1:a7clxaGmmqtdNTXyvrp/lVO/Gnkzlhc/+dLs5v965GM=
@@ -407,7 +397,6 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVD
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -429,14 +418,12 @@ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@@ -467,7 +454,6 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -476,11 +462,8 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -499,7 +482,6 @@ golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -576,7 +558,6 @@ golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@@ -673,7 +654,6 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk= gopkg.in/mail.v2 v2.3.1 h1:WYFn/oANrAGP2C0dcV6/pbkPzv8yGzqTjPmTeO7qoXk=
@@ -684,13 +664,10 @@ gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -128,6 +128,7 @@ type ComplexityRoot struct {
SMTPPort func(childComplexity int) int SMTPPort func(childComplexity int) int
SMTPUsername func(childComplexity int) int SMTPUsername func(childComplexity int) int
SenderEmail func(childComplexity int) int SenderEmail func(childComplexity int) int
SenderName func(childComplexity int) int
TwitterClientID func(childComplexity int) int TwitterClientID func(childComplexity int) int
TwitterClientSecret func(childComplexity int) int TwitterClientSecret func(childComplexity int) int
} }
@@ -143,6 +144,11 @@ type ComplexityRoot struct {
Secret func(childComplexity int) int Secret func(childComplexity int) int
} }
InviteMembersResponse struct {
Message func(childComplexity int) int
Users func(childComplexity int) int
}
Meta struct { Meta struct {
ClientID func(childComplexity int) int ClientID func(childComplexity int) int
IsAppleLoginEnabled func(childComplexity int) int IsAppleLoginEnabled func(childComplexity int) int
@@ -329,7 +335,7 @@ type MutationResolver interface {
AdminLogin(ctx context.Context, params model.AdminLoginInput) (*model.Response, error) AdminLogin(ctx context.Context, params model.AdminLoginInput) (*model.Response, error)
AdminLogout(ctx context.Context) (*model.Response, error) AdminLogout(ctx context.Context) (*model.Response, error)
UpdateEnv(ctx context.Context, params model.UpdateEnvInput) (*model.Response, error) UpdateEnv(ctx context.Context, params model.UpdateEnvInput) (*model.Response, error)
InviteMembers(ctx context.Context, params model.InviteMemberInput) (*model.Response, error) InviteMembers(ctx context.Context, params model.InviteMemberInput) (*model.InviteMembersResponse, error)
RevokeAccess(ctx context.Context, param model.UpdateAccessInput) (*model.Response, error) RevokeAccess(ctx context.Context, param model.UpdateAccessInput) (*model.Response, error)
EnableAccess(ctx context.Context, param model.UpdateAccessInput) (*model.Response, error) EnableAccess(ctx context.Context, param model.UpdateAccessInput) (*model.Response, error)
GenerateJwtKeys(ctx context.Context, params model.GenerateJWTKeysInput) (*model.GenerateJWTKeysResponse, error) GenerateJwtKeys(ctx context.Context, params model.GenerateJWTKeysInput) (*model.GenerateJWTKeysResponse, error)
@@ -890,6 +896,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Env.SenderEmail(childComplexity), true return e.complexity.Env.SenderEmail(childComplexity), true
case "Env.SENDER_NAME":
if e.complexity.Env.SenderName == nil {
break
}
return e.complexity.Env.SenderName(childComplexity), true
case "Env.TWITTER_CLIENT_ID": case "Env.TWITTER_CLIENT_ID":
if e.complexity.Env.TwitterClientID == nil { if e.complexity.Env.TwitterClientID == nil {
break break
@@ -939,6 +952,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.GenerateJWTKeysResponse.Secret(childComplexity), true return e.complexity.GenerateJWTKeysResponse.Secret(childComplexity), true
case "InviteMembersResponse.message":
if e.complexity.InviteMembersResponse.Message == nil {
break
}
return e.complexity.InviteMembersResponse.Message(childComplexity), true
case "InviteMembersResponse.Users":
if e.complexity.InviteMembersResponse.Users == nil {
break
}
return e.complexity.InviteMembersResponse.Users(childComplexity), true
case "Meta.client_id": case "Meta.client_id":
if e.complexity.Meta.ClientID == nil { if e.complexity.Meta.ClientID == nil {
break break
@@ -2160,6 +2187,11 @@ type Response {
message: String! message: String!
} }
type InviteMembersResponse {
message: String!
Users: [User!]!
}
type Env { type Env {
ACCESS_TOKEN_EXPIRY_TIME: String ACCESS_TOKEN_EXPIRY_TIME: String
ADMIN_SECRET: String ADMIN_SECRET: String
@@ -2179,6 +2211,7 @@ type Env {
SMTP_PASSWORD: String SMTP_PASSWORD: String
SMTP_LOCAL_NAME: String SMTP_LOCAL_NAME: String
SENDER_EMAIL: String SENDER_EMAIL: String
SENDER_NAME: String
JWT_TYPE: String JWT_TYPE: String
JWT_SECRET: String JWT_SECRET: String
JWT_PRIVATE_KEY: String JWT_PRIVATE_KEY: String
@@ -2296,6 +2329,7 @@ input UpdateEnvInput {
SMTP_PASSWORD: String SMTP_PASSWORD: String
SMTP_LOCAL_NAME: String SMTP_LOCAL_NAME: String
SENDER_EMAIL: String SENDER_EMAIL: String
SENDER_NAME: String
JWT_TYPE: String JWT_TYPE: String
JWT_SECRET: String JWT_SECRET: String
JWT_PRIVATE_KEY: String JWT_PRIVATE_KEY: String
@@ -2596,7 +2630,8 @@ input ResendOTPRequest {
} }
input GetUserRequest { input GetUserRequest {
id: String! id: String
email: String
} }
type Mutation { type Mutation {
@@ -2621,7 +2656,7 @@ type Mutation {
_admin_login(params: AdminLoginInput!): Response! _admin_login(params: AdminLoginInput!): Response!
_admin_logout: Response! _admin_logout: Response!
_update_env(params: UpdateEnvInput!): Response! _update_env(params: UpdateEnvInput!): Response!
_invite_members(params: InviteMemberInput!): Response! _invite_members(params: InviteMemberInput!): InviteMembersResponse!
_revoke_access(param: UpdateAccessInput!): Response! _revoke_access(param: UpdateAccessInput!): Response!
_enable_access(param: UpdateAccessInput!): Response! _enable_access(param: UpdateAccessInput!): Response!
_generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse! _generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse!
@@ -4771,6 +4806,47 @@ func (ec *executionContext) fieldContext_Env_SENDER_EMAIL(ctx context.Context, f
return fc, nil return fc, nil
} }
func (ec *executionContext) _Env_SENDER_NAME(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Env_SENDER_NAME(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.SenderName, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Env_SENDER_NAME(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 String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Env_JWT_TYPE(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_JWT_TYPE(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Env_JWT_TYPE(ctx, field) fc, err := ec.fieldContext_Env_JWT_TYPE(ctx, field)
if err != nil { if err != nil {
@@ -6737,6 +6813,134 @@ func (ec *executionContext) fieldContext_GenerateJWTKeysResponse_private_key(ctx
return fc, nil return fc, nil
} }
func (ec *executionContext) _InviteMembersResponse_message(ctx context.Context, field graphql.CollectedField, obj *model.InviteMembersResponse) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_InviteMembersResponse_message(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.Message, 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.(string)
fc.Result = res
return ec.marshalNString2string(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_InviteMembersResponse_message(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "InviteMembersResponse",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _InviteMembersResponse_Users(ctx context.Context, field graphql.CollectedField, obj *model.InviteMembersResponse) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_InviteMembersResponse_Users(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.Users, 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_InviteMembersResponse_Users(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "InviteMembersResponse",
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)
}
return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
},
}
return fc, nil
}
func (ec *executionContext) _Meta_version(ctx context.Context, field graphql.CollectedField, obj *model.Meta) (ret graphql.Marshaler) { func (ec *executionContext) _Meta_version(ctx context.Context, field graphql.CollectedField, obj *model.Meta) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Meta_version(ctx, field) fc, err := ec.fieldContext_Meta_version(ctx, field)
if err != nil { if err != nil {
@@ -8689,9 +8893,9 @@ func (ec *executionContext) _Mutation__invite_members(ctx context.Context, field
} }
return graphql.Null return graphql.Null
} }
res := resTmp.(*model.Response) res := resTmp.(*model.InviteMembersResponse)
fc.Result = res fc.Result = res
return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res) return ec.marshalNInviteMembersResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐInviteMembersResponse(ctx, field.Selections, res)
} }
func (ec *executionContext) fieldContext_Mutation__invite_members(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { func (ec *executionContext) fieldContext_Mutation__invite_members(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
@@ -8703,9 +8907,11 @@ func (ec *executionContext) fieldContext_Mutation__invite_members(ctx context.Co
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name { switch field.Name {
case "message": case "message":
return ec.fieldContext_Response_message(ctx, field) return ec.fieldContext_InviteMembersResponse_message(ctx, field)
case "Users":
return ec.fieldContext_InviteMembersResponse_Users(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type Response", field.Name) return nil, fmt.Errorf("no field named %q was found under type InviteMembersResponse", field.Name)
}, },
} }
defer func() { defer func() {
@@ -10126,6 +10332,8 @@ func (ec *executionContext) fieldContext_Query__env(ctx context.Context, field g
return ec.fieldContext_Env_SMTP_LOCAL_NAME(ctx, field) return ec.fieldContext_Env_SMTP_LOCAL_NAME(ctx, field)
case "SENDER_EMAIL": case "SENDER_EMAIL":
return ec.fieldContext_Env_SENDER_EMAIL(ctx, field) return ec.fieldContext_Env_SENDER_EMAIL(ctx, field)
case "SENDER_NAME":
return ec.fieldContext_Env_SENDER_NAME(ctx, field)
case "JWT_TYPE": case "JWT_TYPE":
return ec.fieldContext_Env_JWT_TYPE(ctx, field) return ec.fieldContext_Env_JWT_TYPE(ctx, field)
case "JWT_SECRET": case "JWT_SECRET":
@@ -15162,7 +15370,7 @@ func (ec *executionContext) unmarshalInputGetUserRequest(ctx context.Context, ob
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"id"} fieldsInOrder := [...]string{"id", "email"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -15173,7 +15381,15 @@ func (ec *executionContext) unmarshalInputGetUserRequest(ctx context.Context, ob
var err error var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id"))
it.ID, err = ec.unmarshalNString2string(ctx, v) it.ID, err = ec.unmarshalOString2string(ctx, v)
if err != nil {
return it, err
}
case "email":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email"))
it.Email, err = ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil { if err != nil {
return it, err return it, err
} }
@@ -16122,7 +16338,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", "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"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -16209,6 +16425,14 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
if err != nil { if err != nil {
return it, err return it, err
} }
case "SENDER_NAME":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("SENDER_NAME"))
it.SenderName, err = ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
case "JWT_TYPE": case "JWT_TYPE":
var err error var err error
@@ -17258,6 +17482,10 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, obj
out.Values[i] = ec._Env_SENDER_EMAIL(ctx, field, obj) out.Values[i] = ec._Env_SENDER_EMAIL(ctx, field, obj)
case "SENDER_NAME":
out.Values[i] = ec._Env_SENDER_NAME(ctx, field, obj)
case "JWT_TYPE": case "JWT_TYPE":
out.Values[i] = ec._Env_JWT_TYPE(ctx, field, obj) out.Values[i] = ec._Env_JWT_TYPE(ctx, field, obj)
@@ -17538,6 +17766,41 @@ func (ec *executionContext) _GenerateJWTKeysResponse(ctx context.Context, sel as
return out return out
} }
var inviteMembersResponseImplementors = []string{"InviteMembersResponse"}
func (ec *executionContext) _InviteMembersResponse(ctx context.Context, sel ast.SelectionSet, obj *model.InviteMembersResponse) graphql.Marshaler {
fields := graphql.CollectFields(ec.OperationContext, sel, inviteMembersResponseImplementors)
out := graphql.NewFieldSet(fields)
var invalids uint32
for i, field := range fields {
switch field.Name {
case "__typename":
out.Values[i] = graphql.MarshalString("InviteMembersResponse")
case "message":
out.Values[i] = ec._InviteMembersResponse_message(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
case "Users":
out.Values[i] = ec._InviteMembersResponse_Users(ctx, field, obj)
if out.Values[i] == graphql.Null {
invalids++
}
default:
panic("unknown field " + strconv.Quote(field.Name))
}
}
out.Dispatch()
if invalids > 0 {
return graphql.Null
}
return out
}
var metaImplementors = []string{"Meta"} var metaImplementors = []string{"Meta"}
func (ec *executionContext) _Meta(ctx context.Context, sel ast.SelectionSet, obj *model.Meta) graphql.Marshaler { func (ec *executionContext) _Meta(ctx context.Context, sel ast.SelectionSet, obj *model.Meta) graphql.Marshaler {
@@ -19395,6 +19658,20 @@ func (ec *executionContext) unmarshalNInviteMemberInput2githubᚗcomᚋauthorize
return res, graphql.ErrorOnPath(ctx, err) return res, graphql.ErrorOnPath(ctx, err)
} }
func (ec *executionContext) marshalNInviteMembersResponse2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐInviteMembersResponse(ctx context.Context, sel ast.SelectionSet, v model.InviteMembersResponse) graphql.Marshaler {
return ec._InviteMembersResponse(ctx, sel, &v)
}
func (ec *executionContext) marshalNInviteMembersResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐInviteMembersResponse(ctx context.Context, sel ast.SelectionSet, v *model.InviteMembersResponse) graphql.Marshaler {
if v == nil {
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
ec.Errorf(ctx, "the requested element is null which the schema does not allow")
}
return graphql.Null
}
return ec._InviteMembersResponse(ctx, sel, v)
}
func (ec *executionContext) unmarshalNLoginInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐLoginInput(ctx context.Context, v interface{}) (model.LoginInput, error) { func (ec *executionContext) unmarshalNLoginInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐLoginInput(ctx context.Context, v interface{}) (model.LoginInput, error) {
res, err := ec.unmarshalInputLoginInput(ctx, v) res, err := ec.unmarshalInputLoginInput(ctx, v)
return res, graphql.ErrorOnPath(ctx, err) return res, graphql.ErrorOnPath(ctx, err)

View File

@@ -77,6 +77,7 @@ type Env struct {
SMTPPassword *string `json:"SMTP_PASSWORD"` SMTPPassword *string `json:"SMTP_PASSWORD"`
SMTPLocalName *string `json:"SMTP_LOCAL_NAME"` SMTPLocalName *string `json:"SMTP_LOCAL_NAME"`
SenderEmail *string `json:"SENDER_EMAIL"` SenderEmail *string `json:"SENDER_EMAIL"`
SenderName *string `json:"SENDER_NAME"`
JwtType *string `json:"JWT_TYPE"` JwtType *string `json:"JWT_TYPE"`
JwtSecret *string `json:"JWT_SECRET"` JwtSecret *string `json:"JWT_SECRET"`
JwtPrivateKey *string `json:"JWT_PRIVATE_KEY"` JwtPrivateKey *string `json:"JWT_PRIVATE_KEY"`
@@ -143,7 +144,8 @@ type GenerateJWTKeysResponse struct {
} }
type GetUserRequest struct { type GetUserRequest struct {
ID string `json:"id"` ID *string `json:"id"`
Email *string `json:"email"`
} }
type InviteMemberInput struct { type InviteMemberInput struct {
@@ -151,6 +153,11 @@ type InviteMemberInput struct {
RedirectURI *string `json:"redirect_uri"` RedirectURI *string `json:"redirect_uri"`
} }
type InviteMembersResponse struct {
Message string `json:"message"`
Users []*User `json:"Users"`
}
type ListWebhookLogRequest struct { type ListWebhookLogRequest struct {
Pagination *PaginationInput `json:"pagination"` Pagination *PaginationInput `json:"pagination"`
WebhookID *string `json:"webhook_id"` WebhookID *string `json:"webhook_id"`
@@ -316,6 +323,7 @@ type UpdateEnvInput struct {
SMTPPassword *string `json:"SMTP_PASSWORD"` SMTPPassword *string `json:"SMTP_PASSWORD"`
SMTPLocalName *string `json:"SMTP_LOCAL_NAME"` SMTPLocalName *string `json:"SMTP_LOCAL_NAME"`
SenderEmail *string `json:"SENDER_EMAIL"` SenderEmail *string `json:"SENDER_EMAIL"`
SenderName *string `json:"SENDER_NAME"`
JwtType *string `json:"JWT_TYPE"` JwtType *string `json:"JWT_TYPE"`
JwtSecret *string `json:"JWT_SECRET"` JwtSecret *string `json:"JWT_SECRET"`
JwtPrivateKey *string `json:"JWT_PRIVATE_KEY"` JwtPrivateKey *string `json:"JWT_PRIVATE_KEY"`

View File

@@ -94,6 +94,11 @@ type Response {
message: String! message: String!
} }
type InviteMembersResponse {
message: String!
Users: [User!]!
}
type Env { type Env {
ACCESS_TOKEN_EXPIRY_TIME: String ACCESS_TOKEN_EXPIRY_TIME: String
ADMIN_SECRET: String ADMIN_SECRET: String
@@ -113,6 +118,7 @@ type Env {
SMTP_PASSWORD: String SMTP_PASSWORD: String
SMTP_LOCAL_NAME: String SMTP_LOCAL_NAME: String
SENDER_EMAIL: String SENDER_EMAIL: String
SENDER_NAME: String
JWT_TYPE: String JWT_TYPE: String
JWT_SECRET: String JWT_SECRET: String
JWT_PRIVATE_KEY: String JWT_PRIVATE_KEY: String
@@ -230,6 +236,7 @@ input UpdateEnvInput {
SMTP_PASSWORD: String SMTP_PASSWORD: String
SMTP_LOCAL_NAME: String SMTP_LOCAL_NAME: String
SENDER_EMAIL: String SENDER_EMAIL: String
SENDER_NAME: String
JWT_TYPE: String JWT_TYPE: String
JWT_SECRET: String JWT_SECRET: String
JWT_PRIVATE_KEY: String JWT_PRIVATE_KEY: String
@@ -530,7 +537,8 @@ input ResendOTPRequest {
} }
input GetUserRequest { input GetUserRequest {
id: String! id: String
email: String
} }
type Mutation { type Mutation {
@@ -555,7 +563,7 @@ type Mutation {
_admin_login(params: AdminLoginInput!): Response! _admin_login(params: AdminLoginInput!): Response!
_admin_logout: Response! _admin_logout: Response!
_update_env(params: UpdateEnvInput!): Response! _update_env(params: UpdateEnvInput!): Response!
_invite_members(params: InviteMemberInput!): Response! _invite_members(params: InviteMemberInput!): InviteMembersResponse!
_revoke_access(param: UpdateAccessInput!): Response! _revoke_access(param: UpdateAccessInput!): Response!
_enable_access(param: UpdateAccessInput!): Response! _enable_access(param: UpdateAccessInput!): Response!
_generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse! _generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse!

View File

@@ -112,7 +112,7 @@ func (r *mutationResolver) UpdateEnv(ctx context.Context, params model.UpdateEnv
} }
// InviteMembers is the resolver for the _invite_members field. // InviteMembers is the resolver for the _invite_members field.
func (r *mutationResolver) InviteMembers(ctx context.Context, params model.InviteMemberInput) (*model.Response, error) { func (r *mutationResolver) InviteMembers(ctx context.Context, params model.InviteMemberInput) (*model.InviteMembersResponse, error) {
return resolvers.InviteMembersResolver(ctx, params) return resolvers.InviteMembersResolver(ctx, params)
} }

View File

@@ -194,7 +194,7 @@ func AuthorizeHandler() gin.HandlerFunc {
// rollover the session for security // rollover the session for security
go memorystore.Provider.DeleteUserSession(sessionKey, claims.Nonce) go memorystore.Provider.DeleteUserSession(sessionKey, claims.Nonce)
if responseType == constants.ResponseTypeCode { if responseType == constants.ResponseTypeCode {
newSessionTokenData, newSessionToken, err := token.CreateSessionToken(user, nonce, claims.Roles, scope, claims.LoginMethod) newSessionTokenData, newSessionToken, newSessionExpiresAt, err := token.CreateSessionToken(user, nonce, claims.Roles, scope, claims.LoginMethod)
if err != nil { if err != nil {
log.Debug("CreateSessionToken failed: ", err) log.Debug("CreateSessionToken failed: ", err)
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK) handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
@@ -215,7 +215,7 @@ func AuthorizeHandler() gin.HandlerFunc {
return return
} }
if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+newSessionTokenData.Nonce, newSessionToken); err != nil { if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+newSessionTokenData.Nonce, newSessionToken, newSessionExpiresAt); err != nil {
log.Debug("SetUserSession failed: ", err) log.Debug("SetUserSession failed: ", err)
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK) handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
return return
@@ -271,13 +271,13 @@ func AuthorizeHandler() gin.HandlerFunc {
return return
} }
if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+nonce, authToken.FingerPrintHash); err != nil { if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+nonce, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt); err != nil {
log.Debug("SetUserSession failed: ", err) log.Debug("SetUserSession failed: ", err)
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK) handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
return return
} }
if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+nonce, authToken.AccessToken.Token); err != nil { if err := memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+nonce, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt); err != nil {
log.Debug("SetUserSession failed: ", err) log.Debug("SetUserSession failed: ", err)
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK) handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
return return
@@ -305,7 +305,7 @@ func AuthorizeHandler() gin.HandlerFunc {
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res["refresh_token"] = authToken.RefreshToken.Token res["refresh_token"] = authToken.RefreshToken.Token
params += "&refresh_token=" + authToken.RefreshToken.Token params += "&refresh_token=" + authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
if responseMode == constants.ResponseModeQuery { if responseMode == constants.ResponseModeQuery {

View File

@@ -47,7 +47,14 @@ func LogoutHandler() gin.HandlerFunc {
return return
} }
memorystore.Provider.DeleteUserSession(sessionData.Subject, sessionData.Nonce) userID := sessionData.Subject
loginMethod := sessionData.LoginMethod
sessionToken := userID
if loginMethod != "" {
sessionToken = loginMethod + ":" + userID
}
memorystore.Provider.DeleteUserSession(sessionToken, sessionData.Nonce)
cookie.DeleteSession(gc) cookie.DeleteSession(gc)
if redirectURL != "" { if redirectURL != "" {

View File

@@ -249,12 +249,12 @@ func OAuthCallbackHandler() gin.HandlerFunc {
sessionKey := provider + ":" + user.ID sessionKey := provider + ":" + user.ID
cookie.SetSession(ctx, authToken.FingerPrintHash) cookie.SetSession(ctx, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
params += `&refresh_token=` + authToken.RefreshToken.Token params += `&refresh_token=` + authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
go func() { go func() {
@@ -452,7 +452,7 @@ func processFacebookUserInfo(code string) (models.User, error) {
userRawData := make(map[string]interface{}) userRawData := make(map[string]interface{})
json.Unmarshal(body, &userRawData) json.Unmarshal(body, &userRawData)
email := fmt.Sprintf("%v", userRawData["sub"]) email := fmt.Sprintf("%v", userRawData["email"])
picObject := userRawData["picture"].(map[string]interface{})["data"] picObject := userRawData["picture"].(map[string]interface{})["data"]
picDataObject := picObject.(map[string]interface{}) picDataObject := picObject.(map[string]interface{})

View File

@@ -247,8 +247,8 @@ func TokenHandler() gin.HandlerFunc {
return return
} }
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix() expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
@@ -266,7 +266,7 @@ func TokenHandler() gin.HandlerFunc {
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res["refresh_token"] = authToken.RefreshToken.Token res["refresh_token"] = authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
gc.JSON(http.StatusOK, res) gc.JSON(http.StatusOK, res)

View File

@@ -24,21 +24,22 @@ import (
// It verifies email based on JWT token in query string // It verifies email based on JWT token in query string
func VerifyEmailHandler() gin.HandlerFunc { func VerifyEmailHandler() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
redirectURL := strings.TrimSpace(c.Query("redirect_uri"))
errorRes := gin.H{ errorRes := gin.H{
"error": "invalid_token", "error": "token is required",
} }
tokenInQuery := c.Query("token") tokenInQuery := c.Query("token")
if tokenInQuery == "" { if tokenInQuery == "" {
log.Debug("Token is empty") log.Debug("Token is empty")
c.JSON(400, errorRes) utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return return
} }
verificationRequest, err := db.Provider.GetVerificationRequestByToken(c, tokenInQuery) verificationRequest, err := db.Provider.GetVerificationRequestByToken(c, tokenInQuery)
if err != nil { if err != nil {
log.Debug("Error getting verification request: ", err) log.Debug("Error getting verification request: ", err)
errorRes["error_description"] = err.Error() errorRes["error"] = err.Error()
c.JSON(400, errorRes) utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return return
} }
@@ -47,23 +48,23 @@ func VerifyEmailHandler() gin.HandlerFunc {
claim, err := token.ParseJWTToken(tokenInQuery) claim, err := token.ParseJWTToken(tokenInQuery)
if err != nil { if err != nil {
log.Debug("Error parsing token: ", err) log.Debug("Error parsing token: ", err)
errorRes["error_description"] = err.Error() errorRes["error"] = err.Error()
c.JSON(400, errorRes) utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return return
} }
if ok, err := token.ValidateJWTClaims(claim, hostname, verificationRequest.Nonce, verificationRequest.Email); !ok || err != nil { if ok, err := token.ValidateJWTClaims(claim, hostname, verificationRequest.Nonce, verificationRequest.Email); !ok || err != nil {
log.Debug("Error validating jwt claims: ", err) log.Debug("Error validating jwt claims: ", err)
errorRes["error_description"] = err.Error() errorRes["error"] = err.Error()
c.JSON(400, errorRes) utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return return
} }
user, err := db.Provider.GetUserByEmail(c, verificationRequest.Email) user, err := db.Provider.GetUserByEmail(c, verificationRequest.Email)
if err != nil { if err != nil {
log.Debug("Error getting user: ", err) log.Debug("Error getting user: ", err)
errorRes["error_description"] = err.Error() errorRes["error"] = err.Error()
c.JSON(400, errorRes) utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return return
} }
@@ -79,7 +80,6 @@ func VerifyEmailHandler() gin.HandlerFunc {
db.Provider.DeleteVerificationRequest(c, verificationRequest) db.Provider.DeleteVerificationRequest(c, verificationRequest)
state := strings.TrimSpace(c.Query("state")) state := strings.TrimSpace(c.Query("state"))
redirectURL := strings.TrimSpace(c.Query("redirect_uri"))
rolesString := strings.TrimSpace(c.Query("roles")) rolesString := strings.TrimSpace(c.Query("roles"))
var roles []string var roles []string
if rolesString == "" { if rolesString == "" {
@@ -125,8 +125,8 @@ func VerifyEmailHandler() gin.HandlerFunc {
authToken, err := token.CreateAuthToken(c, user, roles, scope, loginMethod, nonce, code) authToken, err := token.CreateAuthToken(c, user, roles, scope, loginMethod, nonce, code)
if err != nil { if err != nil {
log.Debug("Error creating auth token: ", err) log.Debug("Error creating auth token: ", err)
errorRes["error_description"] = err.Error() errorRes["error"] = err.Error()
c.JSON(500, errorRes) utils.HandleRedirectORJsonResponse(c, http.StatusInternalServerError, errorRes, generateRedirectURL(redirectURL, errorRes))
return return
} }
@@ -135,7 +135,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
// if code != "" { // if code != "" {
// if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil { // if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
// log.Debug("Error setting code state ", err) // log.Debug("Error setting code state ", err)
// errorRes["error_description"] = err.Error() // errorRes["error"] = err.Error()
// c.JSON(500, errorRes) // c.JSON(500, errorRes)
// return // return
// } // }
@@ -154,12 +154,12 @@ func VerifyEmailHandler() gin.HandlerFunc {
sessionKey := loginMethod + ":" + user.ID sessionKey := loginMethod + ":" + user.ID
cookie.SetSession(c, authToken.FingerPrintHash) cookie.SetSession(c, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
params = params + `&refresh_token=` + authToken.RefreshToken.Token params = params + `&refresh_token=` + authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
if redirectURL == "" { if redirectURL == "" {
@@ -189,3 +189,21 @@ func VerifyEmailHandler() gin.HandlerFunc {
c.Redirect(http.StatusTemporaryRedirect, redirectURL) c.Redirect(http.StatusTemporaryRedirect, redirectURL)
} }
} }
func generateRedirectURL(url string, res map[string]interface{}) string {
redirectURL := url
if redirectURL == "" {
return ""
}
var paramsArr []string
for key, value := range res {
paramsArr = append(paramsArr, key+"="+value.(string))
}
params := strings.Join(paramsArr, "&")
if strings.Contains(redirectURL, "?") {
redirectURL = redirectURL + "&" + params
} else {
redirectURL = redirectURL + "?" + strings.TrimPrefix(params, "&")
}
return redirectURL
}

View File

@@ -0,0 +1,14 @@
package inmemory
import (
"testing"
"github.com/authorizerdev/authorizer/server/memorystore/providers"
"github.com/stretchr/testify/assert"
)
func TestInMemoryProvider(t *testing.T) {
p, err := NewInMemoryProvider()
assert.NoError(t, err)
providers.ProviderTests(t, p)
}

View File

@@ -8,45 +8,31 @@ import (
) )
// 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) error { func (c *provider) SetUserSession(userId, key, token string, expiration int64) error {
c.sessionStore.Set(userId, key, token) c.sessionStore.Set(userId, key, token, expiration)
return nil return nil
} }
// GetAllUserSessions returns all the user sessions token from the in-memory store.
func (c *provider) GetAllUserSessions(userId string) (map[string]string, error) {
data := c.sessionStore.GetAll(userId)
return data, nil
}
// GetUserSession returns value for given session token // GetUserSession returns value for given session token
func (c *provider) GetUserSession(userId, sessionToken string) (string, error) { func (c *provider) GetUserSession(userId, sessionToken string) (string, error) {
return c.sessionStore.Get(userId, sessionToken), nil val := c.sessionStore.Get(userId, sessionToken)
if val == "" {
return "", fmt.Errorf("Not found")
}
return val, nil
} }
// DeleteAllUserSessions deletes all the user sessions from in-memory store. // DeleteAllUserSessions deletes all the user sessions from in-memory store.
func (c *provider) DeleteAllUserSessions(userId string) error { func (c *provider) DeleteAllUserSessions(userId string) error {
namespaces := []string{ c.sessionStore.RemoveAll(userId)
constants.AuthRecipeMethodBasicAuth,
constants.AuthRecipeMethodMagicLinkLogin,
constants.AuthRecipeMethodApple,
constants.AuthRecipeMethodFacebook,
constants.AuthRecipeMethodGithub,
constants.AuthRecipeMethodGoogle,
constants.AuthRecipeMethodLinkedIn,
constants.AuthRecipeMethodTwitter,
constants.AuthRecipeMethodMicrosoft,
}
for _, namespace := range namespaces {
c.sessionStore.RemoveAll(namespace + ":" + userId)
}
return nil return nil
} }
// DeleteUserSession deletes the user session from the in-memory store. // DeleteUserSession deletes the user session from the in-memory store.
func (c *provider) DeleteUserSession(userId, sessionToken string) error { func (c *provider) DeleteUserSession(userId, sessionToken string) error {
c.sessionStore.Remove(userId, sessionToken) c.sessionStore.Remove(userId, constants.TokenTypeSessionToken+"_"+sessionToken)
c.sessionStore.Remove(userId, constants.TokenTypeAccessToken+"_"+sessionToken)
c.sessionStore.Remove(userId, constants.TokenTypeRefreshToken+"_"+sessionToken)
return nil return nil
} }

View File

@@ -31,11 +31,15 @@ func (e *EnvStore) UpdateStore(store map[string]interface{}) {
// GetStore returns the env store // GetStore returns the env store
func (e *EnvStore) GetStore() map[string]interface{} { func (e *EnvStore) GetStore() map[string]interface{} {
e.mutex.Lock()
defer e.mutex.Unlock()
return e.store return e.store
} }
// Get returns the value of the key in evn store // Get returns the value of the key in evn store
func (e *EnvStore) Get(key string) interface{} { func (e *EnvStore) Get(key string) interface{} {
e.mutex.Lock()
defer e.mutex.Unlock()
return e.store[key] return e.store[key]
} }

View File

@@ -1,73 +1,140 @@
package stores package stores
import ( import (
"fmt"
"sort"
"strings" "strings"
"sync" "sync"
"time"
) )
const (
// Maximum entries to keep in session storage
maxCacheSize = 1000
// Cache clear interval
clearInterval = 10 * time.Minute
)
// SessionEntry is the struct for entry stored in store
type SessionEntry struct {
Value string
ExpiresAt int64
}
// SessionStore struct to store the env variables // SessionStore struct to store the env variables
type SessionStore struct { type SessionStore struct {
wg sync.WaitGroup
mutex sync.Mutex mutex sync.Mutex
store map[string]map[string]string store map[string]*SessionEntry
// stores expireTime: key to remove data when cache is full
// map is sorted by key so older most entry can be deleted first
keyIndex map[int64]string
stop chan struct{}
} }
// NewSessionStore create a new session store // NewSessionStore create a new session store
func NewSessionStore() *SessionStore { func NewSessionStore() *SessionStore {
return &SessionStore{ store := &SessionStore{
mutex: sync.Mutex{}, mutex: sync.Mutex{},
store: make(map[string]map[string]string), store: make(map[string]*SessionEntry),
keyIndex: make(map[int64]string),
stop: make(chan struct{}),
}
store.wg.Add(1)
go func() {
defer store.wg.Done()
store.clean()
}()
return store
}
func (s *SessionStore) clean() {
t := time.NewTicker(clearInterval)
defer t.Stop()
for {
select {
case <-s.stop:
return
case <-t.C:
s.mutex.Lock()
currentTime := time.Now().Unix()
for k, v := range s.store {
if v.ExpiresAt < currentTime {
delete(s.store, k)
delete(s.keyIndex, v.ExpiresAt)
}
}
s.mutex.Unlock()
}
} }
} }
// Get returns the value of the key in state store // Get returns the value of the key in state store
func (s *SessionStore) Get(key, subKey string) string { func (s *SessionStore) Get(key, subKey string) string {
return s.store[key][subKey] s.mutex.Lock()
defer s.mutex.Unlock()
currentTime := time.Now().Unix()
k := fmt.Sprintf("%s:%s", key, subKey)
if v, ok := s.store[k]; ok {
if v.ExpiresAt > currentTime {
return v.Value
}
// Delete expired items
delete(s.store, k)
}
return ""
} }
// Set sets the value of the key in state store // Set sets the value of the key in state store
func (s *SessionStore) Set(key string, subKey, value string) { func (s *SessionStore) Set(key string, subKey, value string, expiration int64) {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
k := fmt.Sprintf("%s:%s", key, subKey)
if _, ok := s.store[key]; !ok { if _, ok := s.store[k]; !ok {
s.store[key] = make(map[string]string) // check if there is enough space in cache
// else delete entries based on FIFO
if len(s.store) == maxCacheSize {
// remove older most entry
sortedKeys := []int64{}
for ik := range s.keyIndex {
sortedKeys = append(sortedKeys, ik)
} }
s.store[key][subKey] = value sort.Slice(sortedKeys, func(i, j int) bool { return sortedKeys[i] < sortedKeys[j] })
itemToRemove := sortedKeys[0]
delete(s.store, s.keyIndex[itemToRemove])
delete(s.keyIndex, itemToRemove)
}
}
s.store[k] = &SessionEntry{
Value: value,
ExpiresAt: expiration,
}
s.keyIndex[expiration] = k
} }
// RemoveAll all values for given key // RemoveAll all values for given key
func (s *SessionStore) RemoveAll(key string) { func (s *SessionStore) RemoveAll(key string) {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
for k := range s.store {
delete(s.store, key) if strings.Contains(k, key) {
delete(s.store, k)
}
}
} }
// Remove value for given key and subkey // Remove value for given key and subkey
func (s *SessionStore) Remove(key, subKey string) { func (s *SessionStore) Remove(key, subKey string) {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
if _, ok := s.store[key]; ok { k := fmt.Sprintf("%s:%s", key, subKey)
delete(s.store[key], subKey) delete(s.store, k)
}
}
// Get all the values for given key
func (s *SessionStore) GetAll(key string) map[string]string {
s.mutex.Lock()
defer s.mutex.Unlock()
if _, ok := s.store[key]; !ok {
s.store[key] = make(map[string]string)
}
return s.store[key]
} }
// RemoveByNamespace to delete session for a given namespace example google,github // RemoveByNamespace to delete session for a given namespace example google,github
func (s *SessionStore) RemoveByNamespace(namespace string) error { func (s *SessionStore) RemoveByNamespace(namespace string) error {
s.mutex.Lock() s.mutex.Lock()
defer s.mutex.Unlock() defer s.mutex.Unlock()
for key := range s.store { for key := range s.store {
if strings.Contains(key, namespace+":") { if strings.Contains(key, namespace+":") {
delete(s.store, key) delete(s.store, key)

View File

@@ -20,6 +20,8 @@ func NewStateStore() *StateStore {
// Get returns the value of the key in state store // Get returns the value of the key in state store
func (s *StateStore) Get(key string) string { func (s *StateStore) Get(key string) string {
s.mutex.Lock()
defer s.mutex.Unlock()
return s.store[key] return s.store[key]
} }

View File

@@ -0,0 +1,115 @@
package providers
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
// ProviderTests runs all provider tests
func ProviderTests(t *testing.T, p Provider) {
err := p.SetUserSession("auth_provider:123", "session_token_key", "test_hash123", time.Now().Add(60*time.Second).Unix())
assert.NoError(t, err)
err = p.SetUserSession("auth_provider:123", "access_token_key", "test_jwt123", time.Now().Add(60*time.Second).Unix())
assert.NoError(t, err)
// Same user multiple session
err = p.SetUserSession("auth_provider:123", "session_token_key1", "test_hash1123", time.Now().Add(60*time.Second).Unix())
assert.NoError(t, err)
err = p.SetUserSession("auth_provider:123", "access_token_key1", "test_jwt1123", time.Now().Add(60*time.Second).Unix())
assert.NoError(t, err)
// Different user session
err = p.SetUserSession("auth_provider:124", "session_token_key", "test_hash124", time.Now().Add(5*time.Second).Unix())
assert.NoError(t, err)
err = p.SetUserSession("auth_provider:124", "access_token_key", "test_jwt124", time.Now().Add(5*time.Second).Unix())
assert.NoError(t, err)
// Different provider session
err = p.SetUserSession("auth_provider1:124", "session_token_key", "test_hash124", time.Now().Add(60*time.Second).Unix())
assert.NoError(t, err)
err = p.SetUserSession("auth_provider1:124", "access_token_key", "test_jwt124", time.Now().Add(60*time.Second).Unix())
assert.NoError(t, err)
// Different provider session
err = p.SetUserSession("auth_provider1:123", "session_token_key", "test_hash1123", time.Now().Add(60*time.Second).Unix())
assert.NoError(t, err)
err = p.SetUserSession("auth_provider1:123", "access_token_key", "test_jwt1123", time.Now().Add(60*time.Second).Unix())
assert.NoError(t, err)
// Get session
key, err := p.GetUserSession("auth_provider:123", "session_token_key")
assert.NoError(t, err)
assert.Equal(t, "test_hash123", key)
key, err = p.GetUserSession("auth_provider:123", "access_token_key")
assert.NoError(t, err)
assert.Equal(t, "test_jwt123", key)
key, err = p.GetUserSession("auth_provider:124", "session_token_key")
assert.NoError(t, err)
assert.Equal(t, "test_hash124", key)
key, err = p.GetUserSession("auth_provider:124", "access_token_key")
assert.NoError(t, err)
assert.Equal(t, "test_jwt124", key)
// Expire some tokens and make sure they are empty
time.Sleep(5 * time.Second)
key, err = p.GetUserSession("auth_provider:124", "session_token_key")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider:124", "access_token_key")
assert.Empty(t, key)
assert.Error(t, err)
// Delete user session
err = p.DeleteUserSession("auth_provider:123", "key")
assert.NoError(t, err)
err = p.DeleteUserSession("auth_provider:123", "key")
assert.NoError(t, err)
key, err = p.GetUserSession("auth_provider:123", "key")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider:123", "access_token_key")
assert.Empty(t, key)
assert.Error(t, err)
// Delete all user session
err = p.DeleteAllUserSessions("123")
assert.NoError(t, err)
err = p.DeleteAllUserSessions("123")
assert.NoError(t, err)
key, err = p.GetUserSession("auth_provider:123", "session_token_key1")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider:123", "access_token_key1")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider1:123", "session_token_key")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider1:123", "access_token_key")
assert.Empty(t, key)
assert.Error(t, err)
// Delete namespace
err = p.DeleteSessionForNamespace("auth_provider")
assert.NoError(t, err)
err = p.DeleteSessionForNamespace("auth_provider1")
assert.NoError(t, err)
key, err = p.GetUserSession("auth_provider:123", "session_token_key1")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider:123", "access_token_key1")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider1:123", "session_token_key")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider1:123", "access_token_key")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider:124", "session_token_key1")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider:124", "access_token_key1")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider1:124", "session_token_key")
assert.Empty(t, key)
assert.Error(t, err)
key, err = p.GetUserSession("auth_provider1:124", "access_token_key")
assert.Empty(t, key)
assert.Error(t, err)
}

View File

@@ -3,9 +3,7 @@ package providers
// Provider defines current memory store provider // Provider defines current memory store provider
type Provider interface { type Provider interface {
// 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
SetUserSession(userId, key, token string) error SetUserSession(userId, key, token string, expiration int64) error
// GetAllUserSessions returns all the user sessions from the session store
GetAllUserSessions(userId string) (map[string]string, error)
// GetUserSession returns the session token for given token // GetUserSession returns the session token for given token
GetUserSession(userId, key string) (string, error) GetUserSession(userId, key string) (string, error)
// DeleteUserSession deletes the user session // DeleteUserSession deletes the user session

View File

@@ -5,7 +5,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/go-redis/redis/v8" "github.com/redis/go-redis/v9"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
) )
@@ -17,10 +17,11 @@ type RedisClient interface {
HMGet(ctx context.Context, key string, fields ...string) *redis.SliceCmd HMGet(ctx context.Context, key string, fields ...string) *redis.SliceCmd
HSet(ctx context.Context, key string, values ...interface{}) *redis.IntCmd HSet(ctx context.Context, key string, values ...interface{}) *redis.IntCmd
HGet(ctx context.Context, key, field string) *redis.StringCmd HGet(ctx context.Context, key, field string) *redis.StringCmd
HGetAll(ctx context.Context, key string) *redis.StringStringMapCmd HGetAll(ctx context.Context, key string) *redis.MapStringStringCmd
Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd
Get(ctx context.Context, key string) *redis.StringCmd Get(ctx context.Context, key string) *redis.StringCmd
Scan(ctx context.Context, cursor uint64, match string, count int64) *redis.ScanCmd Scan(ctx context.Context, cursor uint64, match string, count int64) *redis.ScanCmd
Keys(ctx context.Context, pattern string) *redis.StringSliceCmd
} }
type provider struct { type provider struct {
@@ -31,7 +32,6 @@ type provider struct {
// NewRedisProvider returns a new redis provider // NewRedisProvider returns a new redis provider
func NewRedisProvider(redisURL string) (*provider, error) { func NewRedisProvider(redisURL string) (*provider, error) {
redisURLHostPortsList := strings.Split(redisURL, ",") redisURLHostPortsList := strings.Split(redisURL, ",")
if len(redisURLHostPortsList) > 1 { if len(redisURLHostPortsList) > 1 {
opt, err := redis.ParseURL(redisURLHostPortsList[0]) opt, err := redis.ParseURL(redisURLHostPortsList[0])
if err != nil { if err != nil {
@@ -70,7 +70,6 @@ func NewRedisProvider(redisURL string) (*provider, error) {
log.Debug("error connecting to redis: ", err) log.Debug("error connecting to redis: ", err)
return nil, err return nil, err
} }
return &provider{ return &provider{
ctx: ctx, ctx: ctx,
store: rdb, store: rdb,

View File

@@ -0,0 +1,15 @@
package redis
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/authorizerdev/authorizer/server/memorystore/providers"
)
func TestRedisProvider(t *testing.T) {
p, err := NewRedisProvider("redis://127.0.0.1:6379")
assert.NoError(t, err)
providers.ProviderTests(t, p)
}

View File

@@ -1,7 +1,9 @@
package redis package redis
import ( import (
"fmt"
"strconv" "strconv"
"time"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@@ -15,29 +17,21 @@ var (
) )
// 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) error { func (c *provider) SetUserSession(userId, key, token string, expiration int64) error {
err := c.store.HSet(c.ctx, userId, key, token).Err() currentTime := time.Now()
expireTime := time.Unix(expiration, 0)
duration := expireTime.Sub(currentTime)
err := c.store.Set(c.ctx, fmt.Sprintf("%s:%s", userId, key), token, duration).Err()
if err != nil { if err != nil {
log.Debug("Error saving to redis: ", err) log.Debug("Error saving user session to redis: ", err)
return err return err
} }
return nil return nil
} }
// GetAllUserSessions returns all the user session token from the redis store.
func (c *provider) GetAllUserSessions(userID string) (map[string]string, error) {
data, err := c.store.HGetAll(c.ctx, userID).Result()
if err != nil {
log.Debug("error getting all user sessions from redis store: ", err)
return nil, err
}
return data, nil
}
// GetUserSession returns the user session from redis store. // GetUserSession returns the user session from redis store.
func (c *provider) GetUserSession(userId, key string) (string, error) { func (c *provider) GetUserSession(userId, key string) (string, error) {
data, err := c.store.HGet(c.ctx, userId, key).Result() data, err := c.store.Get(c.ctx, fmt.Sprintf("%s:%s", userId, key)).Result()
if err != nil { if err != nil {
return "", err return "", err
} }
@@ -46,39 +40,34 @@ func (c *provider) GetUserSession(userId, key string) (string, error) {
// DeleteUserSession deletes the user session from redis store. // DeleteUserSession deletes the user session from redis store.
func (c *provider) DeleteUserSession(userId, key string) error { func (c *provider) DeleteUserSession(userId, key string) error {
if err := c.store.HDel(c.ctx, userId, constants.TokenTypeSessionToken+"_"+key).Err(); err != nil { if err := c.store.Del(c.ctx, fmt.Sprintf("%s:%s", userId, constants.TokenTypeSessionToken+"_"+key)).Err(); err != nil {
log.Debug("Error deleting user session from redis: ", err) log.Debug("Error deleting user session from redis: ", err)
return err // continue
} }
if err := c.store.HDel(c.ctx, userId, constants.TokenTypeAccessToken+"_"+key).Err(); err != nil { if err := c.store.Del(c.ctx, fmt.Sprintf("%s:%s", userId, constants.TokenTypeAccessToken+"_"+key)).Err(); err != nil {
log.Debug("Error deleting user session from redis: ", err) log.Debug("Error deleting user session from redis: ", err)
return err // continue
} }
if err := c.store.HDel(c.ctx, userId, constants.TokenTypeRefreshToken+"_"+key).Err(); err != nil { if err := c.store.Del(c.ctx, fmt.Sprintf("%s:%s", userId, constants.TokenTypeRefreshToken+"_"+key)).Err(); err != nil {
log.Debug("Error deleting user session from redis: ", err) log.Debug("Error deleting user session from redis: ", err)
return err // continue
} }
return nil return nil
} }
// DeleteAllUserSessions deletes all the user session from redis // DeleteAllUserSessions deletes all the user session from redis
func (c *provider) DeleteAllUserSessions(userID string) error { func (c *provider) DeleteAllUserSessions(userID string) error {
namespaces := []string{ res := c.store.Keys(c.ctx, fmt.Sprintf("*%s*", userID))
constants.AuthRecipeMethodBasicAuth, if res.Err() != nil {
constants.AuthRecipeMethodMagicLinkLogin, log.Debug("Error getting all user sessions from redis: ", res.Err())
constants.AuthRecipeMethodApple, return res.Err()
constants.AuthRecipeMethodFacebook,
constants.AuthRecipeMethodGithub,
constants.AuthRecipeMethodGoogle,
constants.AuthRecipeMethodLinkedIn,
constants.AuthRecipeMethodTwitter,
constants.AuthRecipeMethodMicrosoft,
} }
for _, namespace := range namespaces { keys := res.Val()
err := c.store.Del(c.ctx, namespace+":"+userID).Err() for _, key := range keys {
err := c.store.Del(c.ctx, key).Err()
if err != nil { if err != nil {
log.Debug("Error deleting all user sessions from redis: ", err) log.Debug("Error deleting all user sessions from redis: ", err)
return err continue
} }
} }
return nil return nil
@@ -86,27 +75,19 @@ func (c *provider) DeleteAllUserSessions(userID string) error {
// DeleteSessionForNamespace to delete session for a given namespace example google,github // DeleteSessionForNamespace to delete session for a given namespace example google,github
func (c *provider) DeleteSessionForNamespace(namespace string) error { func (c *provider) DeleteSessionForNamespace(namespace string) error {
var cursor uint64 res := c.store.Keys(c.ctx, fmt.Sprintf("%s:*", namespace))
for { if res.Err() != nil {
keys := []string{} log.Debug("Error getting all user sessions from redis: ", res.Err())
keys, cursor, err := c.store.Scan(c.ctx, cursor, namespace+":*", 0).Result() return res.Err()
if err != nil {
log.Debugf("Error scanning keys for %s namespace: %s", namespace, err.Error())
return err
} }
keys := res.Val()
for _, key := range keys { for _, key := range keys {
err := c.store.Del(c.ctx, key).Err() err := c.store.Del(c.ctx, key).Err()
if err != nil { if err != nil {
log.Debugf("Error deleting sessions for %s namespace: %s", namespace, err.Error()) log.Debug("Error deleting all user sessions from redis: ", err)
return err continue
} }
} }
if cursor == 0 { // no more keys
break
}
}
return nil return nil
} }

View File

@@ -89,6 +89,9 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
if val, ok := store[constants.EnvKeySenderEmail]; ok { if val, ok := store[constants.EnvKeySenderEmail]; ok {
res.SenderEmail = refs.NewStringRef(val.(string)) res.SenderEmail = refs.NewStringRef(val.(string))
} }
if val, ok := store[constants.EnvKeySenderName]; ok {
res.SenderName = refs.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeySmtpLocalName]; ok { if val, ok := store[constants.EnvKeySmtpLocalName]; ok {
res.SMTPLocalName = refs.NewStringRef(val.(string)) res.SMTPLocalName = refs.NewStringRef(val.(string))
} }

View File

@@ -23,7 +23,7 @@ import (
) )
// InviteMembersResolver resolver to invite members // InviteMembersResolver resolver to invite members
func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput) (*model.Response, error) { func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput) (*model.InviteMembersResponse, error) {
gc, err := utils.GinContextFromContext(ctx) gc, err := utils.GinContextFromContext(ctx)
if err != nil { if err != nil {
log.Debug("Failed to get GinContext: ", err) log.Debug("Failed to get GinContext: ", err)
@@ -178,7 +178,25 @@ func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput)
}) })
} }
return &model.Response{ InvitedUsers := []*model.User{}
for _, email := range newEmails {
user, err := db.Provider.GetUserByEmail(ctx, email)
if err != nil {
log.Debugf("err: %s", err.Error())
return nil, err
}
InvitedUsers = append(InvitedUsers, &model.User{
Email: user.Email,
ID: user.ID,
})
}
return &model.InviteMembersResponse{
Message: fmt.Sprintf("%d user(s) invited successfully.", len(newEmails)), Message: fmt.Sprintf("%d user(s) invited successfully.", len(newEmails)),
Users: InvitedUsers,
}, nil }, nil
} }

View File

@@ -193,12 +193,12 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
sessionStoreKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID sessionStoreKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token) memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
go func() { go func() {

View File

@@ -224,7 +224,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
go email.SendEmail([]string{params.Email}, constants.VerificationTypeMagicLinkLogin, map[string]interface{}{ go email.SendEmail([]string{params.Email}, constants.VerificationTypeMagicLinkLogin, map[string]interface{}{
"user": user.ToMap(), "user": user.ToMap(),
"organization": utils.GetOrganization(), "organization": utils.GetOrganization(),
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname), "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
}) })
} }

View File

@@ -195,12 +195,12 @@ func MobileLoginResolver(ctx context.Context, params model.MobileLoginInput) (*m
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
sessionStoreKey := constants.AuthRecipeMethodMobileBasicAuth + ":" + user.ID sessionStoreKey := constants.AuthRecipeMethodMobileBasicAuth + ":" + user.ID
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token) memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
go func() { go func() {

View File

@@ -249,12 +249,12 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput)
sessionKey := constants.AuthRecipeMethodMobileBasicAuth + ":" + user.ID sessionKey := constants.AuthRecipeMethodMobileBasicAuth + ":" + user.ID
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
go func() { go func() {

View File

@@ -83,7 +83,7 @@ func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEma
go email.SendEmail([]string{params.Email}, params.Identifier, map[string]interface{}{ go email.SendEmail([]string{params.Email}, params.Identifier, map[string]interface{}{
"user": user.ToMap(), "user": user.ToMap(),
"organization": utils.GetOrganization(), "organization": utils.GetOrganization(),
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname), "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, verificationRequest.RedirectURI),
}) })
res = &model.Response{ res = &model.Response{

View File

@@ -99,12 +99,12 @@ func SessionResolver(ctx context.Context, params *model.SessionQueryInput) (*mod
} }
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
return res, nil return res, nil
} }

View File

@@ -91,7 +91,6 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
} }
inputRoles := []string{} inputRoles := []string{}
if len(params.Roles) > 0 { if len(params.Roles) > 0 {
// check if roles exists // check if roles exists
rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles) rolesString, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyRoles)
@@ -228,7 +227,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
email.SendEmail([]string{params.Email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{ email.SendEmail([]string{params.Email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{
"user": user.ToMap(), "user": user.ToMap(),
"organization": utils.GetOrganization(), "organization": utils.GetOrganization(),
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname), "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
}) })
utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user) utils.RegisterEvent(ctx, constants.UserCreatedWebhookEvent, constants.AuthRecipeMethodBasicAuth, user)
}() }()
@@ -293,12 +292,12 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID sessionKey := constants.AuthRecipeMethodBasicAuth + ":" + user.ID
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
go func() { go func() {

View File

@@ -259,7 +259,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
go email.SendEmail([]string{user.Email}, verificationType, map[string]interface{}{ go email.SendEmail([]string{user.Email}, verificationType, map[string]interface{}{
"user": user.ToMap(), "user": user.ToMap(),
"organization": utils.GetOrganization(), "organization": utils.GetOrganization(),
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname), "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
}) })
} }

View File

@@ -164,7 +164,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
go email.SendEmail([]string{user.Email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{ go email.SendEmail([]string{user.Email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{
"user": user.ToMap(), "user": user.ToMap(),
"organization": utils.GetOrganization(), "organization": utils.GetOrganization(),
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname), "verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
}) })
} }

View File

@@ -3,6 +3,7 @@ package resolvers
import ( import (
"context" "context"
"fmt" "fmt"
"strings"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
@@ -20,17 +21,28 @@ func UserResolver(ctx context.Context, params model.GetUserRequest) (*model.User
log.Debug("Failed to get GinContext: ", err) log.Debug("Failed to get GinContext: ", err)
return nil, err return nil, err
} }
if !token.IsSuperAdmin(gc) { if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin.") log.Debug("Not logged in as super admin.")
return nil, fmt.Errorf("unauthorized") return nil, fmt.Errorf("unauthorized")
} }
// Try getting user by ID
res, err := db.Provider.GetUserByID(ctx, params.ID) if params.ID != nil && strings.Trim(*params.ID, " ") != "" {
res, err := db.Provider.GetUserByID(ctx, *params.ID)
if err != nil { if err != nil {
log.Debug("Failed to get users: ", err) log.Debug("Failed to get users by ID: ", err)
return nil, err return nil, err
} }
return res.AsAPIUser(), nil return res.AsAPIUser(), nil
}
// Try getting user by email
if params.Email != nil && strings.Trim(*params.Email, " ") != "" {
res, err := db.Provider.GetUserByEmail(ctx, *params.Email)
if err != nil {
log.Debug("Failed to get users by email: ", err)
return nil, err
}
return res.AsAPIUser(), nil
}
// Return error if no params are provided
return nil, fmt.Errorf("invalid params, user id or email is required")
} }

View File

@@ -150,12 +150,12 @@ func VerifyEmailResolver(ctx context.Context, params model.VerifyEmailInput) (*m
sessionKey := loginMethod + ":" + user.ID sessionKey := loginMethod + ":" + user.ID
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
return res, nil return res, nil
} }

View File

@@ -123,12 +123,12 @@ func VerifyOtpResolver(ctx context.Context, params model.VerifyOTPRequest) (*mod
sessionKey := loginMethod + ":" + user.ID sessionKey := loginMethod + ":" + user.ID
cookie.SetSession(gc, authToken.FingerPrintHash) cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
res.RefreshToken = &authToken.RefreshToken.Token res.RefreshToken = &authToken.RefreshToken.Token
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
return res, nil return res, nil
} }

View File

@@ -49,6 +49,8 @@ func inviteUserTest(t *testing.T, s TestSetup) {
}) })
assert.Nil(t, err) assert.Nil(t, err)
assert.NotNil(t, res) assert.NotNil(t, res)
assert.NotNil(t, res.Message)
assert.NotNil(t, res.Users)
// duplicate error test // duplicate error test
res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{ res, err = resolvers.InviteMembersResolver(ctx, model.InviteMemberInput{
Emails: emails, Emails: emails,

View File

@@ -8,6 +8,7 @@ import (
"github.com/authorizerdev/authorizer/server/crypto" "github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/refs"
"github.com/authorizerdev/authorizer/server/resolvers" "github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -26,7 +27,7 @@ func userTest(t *testing.T, s TestSetup) {
assert.NotEmpty(t, res.User) assert.NotEmpty(t, res.User)
userRes, err := resolvers.UserResolver(ctx, model.GetUserRequest{ userRes, err := resolvers.UserResolver(ctx, model.GetUserRequest{
ID: res.User.ID, ID: &res.User.ID,
}) })
assert.Nil(t, userRes) assert.Nil(t, userRes)
assert.NotNil(t, err, "unauthorized") assert.NotNil(t, err, "unauthorized")
@@ -36,14 +37,36 @@ func userTest(t *testing.T, s TestSetup) {
h, err := crypto.EncryptPassword(adminSecret) h, err := crypto.EncryptPassword(adminSecret)
assert.Nil(t, err) assert.Nil(t, err)
req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h)) req.Header.Set("Cookie", fmt.Sprintf("%s=%s", constants.AdminCookieName, h))
// Should throw error for invalid params
userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{})
assert.Nil(t, userRes)
assert.NotNil(t, err, "invalid params, user id or email is required")
// Should throw error for invalid params with empty id
userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{ userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
ID: res.User.ID, ID: refs.NewStringRef(" "),
})
assert.Nil(t, userRes)
assert.NotNil(t, err, "invalid params, user id or email is required")
// Should throw error for invalid params with empty email
userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
Email: refs.NewStringRef(" "),
})
assert.Nil(t, userRes)
assert.NotNil(t, err, "invalid params, user id or email is required")
// Should get user by id
userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
ID: &res.User.ID,
})
assert.Nil(t, err)
assert.Equal(t, res.User.ID, userRes.ID)
assert.Equal(t, email, userRes.Email)
// Should get user by email
userRes, err = resolvers.UserResolver(ctx, model.GetUserRequest{
Email: &email,
}) })
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, res.User.ID, userRes.ID) assert.Equal(t, res.User.ID, userRes.ID)
assert.Equal(t, email, userRes.Email) assert.Equal(t, email, userRes.Email)
cleanData(email) cleanData(email)
}) })
} }

View File

@@ -55,11 +55,11 @@ func validateJwtTokenTest(t *testing.T, s TestSetup) {
authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, "") authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth, nonce, "")
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, authToken) assert.NotNil(t, authToken)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil { if authToken.RefreshToken != nil {
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token) memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeRefreshToken+"_"+authToken.FingerPrint, authToken.RefreshToken.Token, authToken.RefreshToken.ExpiresAt)
} }
t.Run(`should validate the access token`, func(t *testing.T) { t.Run(`should validate the access token`, func(t *testing.T) {

View File

@@ -31,7 +31,9 @@ type JWTToken struct {
// Token object to hold the finger print and refresh token information // Token object to hold the finger print and refresh token information
type Token struct { type Token struct {
FingerPrint string `json:"fingerprint"` FingerPrint string `json:"fingerprint"`
// Session Token
FingerPrintHash string `json:"fingerprint_hash"` FingerPrintHash string `json:"fingerprint_hash"`
SessionTokenExpiresAt int64 `json:"expires_at"`
RefreshToken *JWTToken `json:"refresh_token"` RefreshToken *JWTToken `json:"refresh_token"`
AccessToken *JWTToken `json:"access_token"` AccessToken *JWTToken `json:"access_token"`
IDToken *JWTToken `json:"id_token"` IDToken *JWTToken `json:"id_token"`
@@ -51,7 +53,7 @@ type SessionData struct {
// CreateAuthToken creates a new auth token when userlogs in // CreateAuthToken creates a new auth token when userlogs in
func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, loginMethod, nonce string, code string) (*Token, error) { func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, loginMethod, nonce string, code string) (*Token, error) {
hostname := parsers.GetHost(gc) hostname := parsers.GetHost(gc)
_, fingerPrintHash, err := CreateSessionToken(user, nonce, roles, scope, loginMethod) _, fingerPrintHash, sessionTokenExpiresAt, err := CreateSessionToken(user, nonce, roles, scope, loginMethod)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -84,6 +86,7 @@ func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, l
res := &Token{ res := &Token{
FingerPrint: nonce, FingerPrint: nonce,
FingerPrintHash: fingerPrintHash, FingerPrintHash: fingerPrintHash,
SessionTokenExpiresAt: sessionTokenExpiresAt,
AccessToken: &JWTToken{Token: accessToken, ExpiresAt: accessTokenExpiresAt}, AccessToken: &JWTToken{Token: accessToken, ExpiresAt: accessTokenExpiresAt},
IDToken: &JWTToken{Token: idToken, ExpiresAt: idTokenExpiresAt}, IDToken: &JWTToken{Token: idToken, ExpiresAt: idTokenExpiresAt},
} }
@@ -101,7 +104,8 @@ func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, l
} }
// CreateSessionToken creates a new session token // CreateSessionToken creates a new session token
func CreateSessionToken(user models.User, nonce string, roles, scope []string, loginMethod string) (*SessionData, string, error) { func CreateSessionToken(user models.User, nonce string, roles, scope []string, loginMethod string) (*SessionData, string, int64, error) {
expiresAt := time.Now().AddDate(1, 0, 0).Unix()
fingerPrintMap := &SessionData{ fingerPrintMap := &SessionData{
Nonce: nonce, Nonce: nonce,
Roles: roles, Roles: roles,
@@ -109,15 +113,15 @@ func CreateSessionToken(user models.User, nonce string, roles, scope []string, l
Scope: scope, Scope: scope,
LoginMethod: loginMethod, LoginMethod: loginMethod,
IssuedAt: time.Now().Unix(), IssuedAt: time.Now().Unix(),
ExpiresAt: time.Now().AddDate(1, 0, 0).Unix(), ExpiresAt: expiresAt,
} }
fingerPrintBytes, _ := json.Marshal(fingerPrintMap) fingerPrintBytes, _ := json.Marshal(fingerPrintMap)
fingerPrintHash, err := crypto.EncryptAES(string(fingerPrintBytes)) fingerPrintHash, err := crypto.EncryptAES(string(fingerPrintBytes))
if err != nil { if err != nil {
return nil, "", err return nil, "", 0, err
} }
return fingerPrintMap, fingerPrintHash, nil return fingerPrintMap, fingerPrintHash, expiresAt, nil
} }
// CreateRefreshToken util to create JWT token // CreateRefreshToken util to create JWT token

View File

@@ -92,6 +92,6 @@ func GetInviteVerificationURL(verificationURL, token, redirectURI string) string
} }
// GetEmailVerificationURL to get url for invite email verification // GetEmailVerificationURL to get url for invite email verification
func GetEmailVerificationURL(token, hostname string) string { func GetEmailVerificationURL(token, hostname, redirectURI string) string {
return hostname + "/verify_email?token=" + token return hostname + "/verify_email?token=" + token + "&redirect_uri=" + redirectURI
} }

17
server/utils/response.go Normal file
View File

@@ -0,0 +1,17 @@
package utils
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
)
// HandleRedirectORJsonResponse handles the response based on redirectURL
func HandleRedirectORJsonResponse(c *gin.Context, httpResponse int, response map[string]interface{}, redirectURL string) {
if strings.TrimSpace(redirectURL) == "" {
c.JSON(httpResponse, response)
} else {
c.Redirect(http.StatusTemporaryRedirect, redirectURL)
}
}