Compare commits

...

36 Commits

Author SHA1 Message Date
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
Lakhan Samani
c8fe05eabc Merge pull request #342 from authorizerdev/feat/default-oauth-configs
feat: add support for default response mode & type env
2023-04-01 17:42:02 +05:30
Lakhan Samani
48344ffd4c feat: add support for default response mode & type env
Resolves #341
2023-04-01 17:36:07 +05:30
60 changed files with 4284 additions and 2056 deletions

View File

@@ -7,4 +7,5 @@ SMTP_PORT=2525
SMTP_USERNAME=test
SMTP_PASSWORD=test
SENDER_EMAIL="info@authorizer.dev"
SENDER_NAME="Authorizer"
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**)
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`
5. 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`
7. Build App `make build-app`
8. Build Server `make clean && make`
4. Create Env file `cp .env.sample .env`. Check all the supported env [here](https://docs.authorizer.dev/core/env/)
5. Build Dashboard `make build-dashboard`
6. Build App `make build-app`
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.
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
@@ -87,145 +105,145 @@ For manually testing using graphql playground, you can paste following queries a
```gql
mutation Signup {
signup(
params: {
email: "lakhan@yopmail.com"
password: "test"
confirm_password: "test"
given_name: "lakhan"
}
) {
message
user {
id
family_name
given_name
email
email_verified
}
}
signup(
params: {
email: "lakhan@yopmail.com"
password: "test"
confirm_password: "test"
given_name: "lakhan"
}
) {
message
user {
id
family_name
given_name
email
email_verified
}
}
}
mutation ResendEamil {
resend_verify_email(
params: { email: "lakhan@yopmail.com", identifier: "basic_auth_signup" }
) {
message
}
resend_verify_email(
params: { email: "lakhan@yopmail.com", identifier: "basic_auth_signup" }
) {
message
}
}
query GetVerifyRequests {
_verification_requests {
id
token
expires
identifier
}
_verification_requests {
id
token
expires
identifier
}
}
mutation VerifyEmail {
verify_email(params: { token: "" }) {
access_token
expires_at
user {
id
email
given_name
email_verified
}
}
verify_email(params: { token: "" }) {
access_token
expires_at
user {
id
email
given_name
email_verified
}
}
}
mutation Login {
login(params: { email: "lakhan@yopmail.com", password: "test" }) {
access_token
expires_at
user {
id
family_name
given_name
email
}
}
login(params: { email: "lakhan@yopmail.com", password: "test" }) {
access_token
expires_at
user {
id
family_name
given_name
email
}
}
}
query GetSession {
session {
access_token
expires_at
user {
id
given_name
family_name
email
email_verified
signup_methods
created_at
updated_at
}
}
session {
access_token
expires_at
user {
id
given_name
family_name
email
email_verified
signup_methods
created_at
updated_at
}
}
}
mutation ForgotPassword {
forgot_password(params: { email: "lakhan@yopmail.com" }) {
message
}
forgot_password(params: { email: "lakhan@yopmail.com" }) {
message
}
}
mutation ResetPassword {
reset_password(
params: { token: "", password: "test", confirm_password: "test" }
) {
message
}
reset_password(
params: { token: "", password: "test", confirm_password: "test" }
) {
message
}
}
mutation UpdateProfile {
update_profile(params: { family_name: "samani" }) {
message
}
update_profile(params: { family_name: "samani" }) {
message
}
}
query GetUsers {
_users {
id
email
email_verified
given_name
family_name
picture
signup_methods
phone_number
}
_users {
id
email
email_verified
given_name
family_name
picture
signup_methods
phone_number
}
}
mutation MagicLinkLogin {
magic_link_login(params: { email: "test@yopmail.com" }) {
message
}
magic_link_login(params: { email: "test@yopmail.com" }) {
message
}
}
mutation Logout {
logout {
message
}
logout {
message
}
}
mutation UpdateUser {
_update_user(
params: {
id: "dafc9400-d603-4ade-997c-83fcd54bbd67"
roles: ["user", "admin"]
}
) {
email
roles
}
_update_user(
params: {
id: "dafc9400-d603-4ade-997c-83fcd54bbd67"
roles: ["user", "admin"]
}
) {
email
roles
}
}
mutation DeleteUser {
_delete_user(params: { email: "signup.test134523@yopmail.com" }) {
message
}
_delete_user(params: { email: "signup.test134523@yopmail.com" }) {
message
}
}
```

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -126,6 +126,22 @@ const EmailConfigurations = ({
/>
</Center>
</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>
</div>
);

View File

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

View File

@@ -61,7 +61,6 @@ const JSTConfigurations = ({
return (
<div>
{' '}
<Flex
borderRadius={5}
width="100%"

View File

@@ -18,7 +18,13 @@ import {
FaTwitter,
FaMicrosoft,
} from 'react-icons/fa';
import { TextInputType, HiddenInputType } from '../../constants';
import {
TextInputType,
HiddenInputType,
ResponseModes,
ResponseTypes,
SelectInputType,
} from '../../constants';
const OAuthConfig = ({
envVariables,
@@ -70,6 +76,42 @@ const OAuthConfig = ({
/>
</Center>
</Flex>
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
<Flex w="30%" justifyContent="start" alignItems="center">
<Text fontSize="sm">Default Response Type:</Text>
</Flex>
<Flex
w={isNotSmallerScreen ? '70%' : '100%'}
mt={isNotSmallerScreen ? '0' : '2'}
>
<InputField
borderRadius={5}
variables={envVariables}
setVariables={setVariables}
inputType={SelectInputType.DEFAULT_AUTHORIZE_RESPONSE_TYPE}
value={SelectInputType}
options={ResponseTypes}
/>
</Flex>
</Flex>
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
<Flex w="30%" justifyContent="start" alignItems="center">
<Text fontSize="sm">Default Response Mode:</Text>
</Flex>
<Flex
w={isNotSmallerScreen ? '70%' : '100%'}
mt={isNotSmallerScreen ? '0' : '2'}
>
<InputField
borderRadius={5}
variables={envVariables}
setVariables={setVariables}
inputType={SelectInputType.DEFAULT_AUTHORIZE_RESPONSE_MODE}
value={SelectInputType}
options={ResponseModes}
/>
</Flex>
</Flex>
</Stack>
<Divider mt={5} mb={2} color="blackAlpha.700" />
<Text fontSize="md" paddingTop="2%" fontWeight="bold" mb={4}>

View File

@@ -48,6 +48,8 @@ const InputField = ({
fieldVisibility,
setFieldVisibility,
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
}: any) => {
const props = {
@@ -398,7 +400,9 @@ const InputField = ({
</Text>
<Switch
size="md"
isChecked={variables[inputType]}
isChecked={
hasReversedValue ? !variables[inputType] : variables[inputType]
}
onChange={() => {
setVariables({
...variables,

View File

@@ -19,6 +19,7 @@ export const TextInputType = {
SMTP_USERNAME: 'SMTP_USERNAME',
SMTP_LOCAL_NAME: 'SMTP_LOCAL_NAME',
SENDER_EMAIL: 'SENDER_EMAIL',
SENDER_NAME: 'SENDER_NAME',
ORGANIZATION_NAME: 'ORGANIZATION_NAME',
ORGANIZATION_LOGO: 'ORGANIZATION_LOGO',
DATABASE_NAME: 'DATABASE_NAME',
@@ -57,6 +58,8 @@ export const ArrayInputType = {
export const SelectInputType = {
JWT_TYPE: 'JWT_TYPE',
GENDER: 'gender',
DEFAULT_AUTHORIZE_RESPONSE_TYPE: 'DEFAULT_AUTHORIZE_RESPONSE_TYPE',
DEFAULT_AUTHORIZE_RESPONSE_MODE: 'DEFAULT_AUTHORIZE_RESPONSE_MODE',
};
export const MultiSelectInputType = {
@@ -141,6 +144,7 @@ export interface envVarTypes {
SMTP_PASSWORD: string;
SMTP_LOCAL_NAME: string;
SENDER_EMAIL: string;
SENDER_NAME: string;
ALLOWED_ORIGINS: [string] | [];
ORGANIZATION_NAME: string;
ORGANIZATION_LOGO: string;
@@ -161,6 +165,8 @@ export interface envVarTypes {
ACCESS_TOKEN_EXPIRY_TIME: string;
DISABLE_MULTI_FACTOR_AUTHENTICATION: boolean;
ENFORCE_MULTI_FACTOR_AUTHENTICATION: boolean;
DEFAULT_AUTHORIZE_RESPONSE_TYPE: string;
DEFAULT_AUTHORIZE_RESPONSE_MODE: string;
}
export const envSubViews = {
@@ -349,3 +355,16 @@ export enum EmailTemplateEditors {
UNLAYER_EDITOR = 'unlayer_editor',
PLAIN_HTML_EDITOR = 'plain_html_editor',
}
export const ResponseTypes = {
token: 'token',
code: 'code',
id_token: 'id_token',
};
export const ResponseModes = {
query: 'query',
form_post: 'form_post',
fragment: 'fragment',
web_message: 'web_message',
};

View File

@@ -50,6 +50,7 @@ export const EnvVariablesQuery = `
SMTP_PASSWORD
SMTP_LOCAL_NAME
SENDER_EMAIL
SENDER_NAME
ALLOWED_ORIGINS
ORGANIZATION_NAME
ORGANIZATION_LOGO
@@ -70,6 +71,8 @@ export const EnvVariablesQuery = `
ACCESS_TOKEN_EXPIRY_TIME
DISABLE_MULTI_FACTOR_AUTHENTICATION
ENFORCE_MULTI_FACTOR_AUTHENTICATION
DEFAULT_AUTHORIZE_RESPONSE_TYPE
DEFAULT_AUTHORIZE_RESPONSE_MODE
}
}
`;

View File

@@ -70,6 +70,7 @@ const Environment = () => {
SMTP_PASSWORD: '',
SMTP_LOCAL_NAME: '',
SENDER_EMAIL: '',
SENDER_NAME: '',
ALLOWED_ORIGINS: [],
ORGANIZATION_NAME: '',
ORGANIZATION_LOGO: '',
@@ -90,6 +91,8 @@ const Environment = () => {
ACCESS_TOKEN_EXPIRY_TIME: '',
DISABLE_MULTI_FACTOR_AUTHENTICATION: false,
ENFORCE_MULTI_FACTOR_AUTHENTICATION: false,
DEFAULT_AUTHORIZE_RESPONSE_TYPE: '',
DEFAULT_AUTHORIZE_RESPONSE_MODE: '',
});
const [fieldVisibility, setFieldVisibility] = React.useState<

File diff suppressed because it is too large Load Diff

View File

@@ -62,6 +62,8 @@ const (
EnvKeySmtpLocalName = "SMTP_LOCAL_NAME"
// EnvKeySenderEmail key for env variable 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 = "IS_EMAIL_SERVICE_ENABLED"
// EnvKeyAppCookieSecure key for env variable APP_COOKIE_SECURE
@@ -166,4 +168,12 @@ const (
EnvKeyDefaultRoles = "DEFAULT_ROLES"
// EnvKeyAllowedOrigins key for env variable ALLOWED_ORIGINS
EnvKeyAllowedOrigins = "ALLOWED_ORIGINS"
// For oauth/openid/authorize
// EnvKeyDefaultAuthorizeResponseType key for env variable DEFAULT_AUTHORIZE_RESPONSE_TYPE
// This env is used for setting default response type in authorize handler
EnvKeyDefaultAuthorizeResponseType = "DEFAULT_AUTHORIZE_RESPONSE_TYPE"
// EnvKeyDefaultAuthorizeResponseMode key for env variable DEFAULT_AUTHORIZE_RESPONSE_MODE
// This env is used for setting default response mode in authorize handler
EnvKeyDefaultAuthorizeResponseMode = "DEFAULT_AUTHORIZE_RESPONSE_MODE"
)

View File

@@ -103,6 +103,12 @@ func SendEmail(to []string, event string, data map[string]interface{}) error {
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)
if err != nil {
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
}
m.SetHeader("From", senderEmail)
m.SetAddressHeader("From", senderEmail, senderName)
m.SetHeader("To", to...)
m.SetHeader("Subject", tmp.Subject)
m.SetBody("text/html", tmp.Template)

32
server/env/env.go vendored
View File

@@ -57,6 +57,7 @@ func InitAllEnv() error {
osSmtpPassword := os.Getenv(constants.EnvKeySmtpPassword)
osSmtpLocalName := os.Getenv(constants.EnvKeySmtpLocalName)
osSenderEmail := os.Getenv(constants.EnvKeySenderEmail)
osSenderName := os.Getenv(constants.EnvKeySenderName)
osJwtType := os.Getenv(constants.EnvKeyJwtType)
osJwtSecret := os.Getenv(constants.EnvKeyJwtSecret)
osJwtPrivateKey := os.Getenv(constants.EnvKeyJwtPrivateKey)
@@ -87,6 +88,8 @@ func InitAllEnv() error {
osCouchbaseBucket := os.Getenv(constants.EnvCouchbaseBucket)
osCouchbaseScope := os.Getenv(constants.EnvCouchbaseScope)
osCouchbaseBucketRAMQuotaMB := os.Getenv(constants.EnvCouchbaseBucketRAMQuotaMB)
osAuthorizeResponseType := os.Getenv(constants.EnvKeyDefaultAuthorizeResponseType)
osAuthorizeResponseMode := os.Getenv(constants.EnvKeyDefaultAuthorizeResponseMode)
// os bool vars
osAppCookieSecure := os.Getenv(constants.EnvKeyAppCookieSecure)
@@ -255,6 +258,13 @@ func InitAllEnv() error {
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]
algo := ""
if !ok || algoVal == "" {
@@ -735,6 +745,28 @@ func InitAllEnv() error {
envData[constants.EnvKeyProtectedRoles] = osProtectedRoles
}
if val, ok := envData[constants.EnvKeyDefaultAuthorizeResponseType]; !ok || val == "" {
envData[constants.EnvKeyDefaultAuthorizeResponseType] = osAuthorizeResponseType
// Set the default value to token type
if envData[constants.EnvKeyDefaultAuthorizeResponseType] == "" {
envData[constants.EnvKeyDefaultAuthorizeResponseType] = constants.ResponseTypeToken
}
}
if osAuthorizeResponseType != "" && envData[constants.EnvKeyDefaultAuthorizeResponseType] != osAuthorizeResponseType {
envData[constants.EnvKeyDefaultAuthorizeResponseType] = osAuthorizeResponseType
}
if val, ok := envData[constants.EnvKeyDefaultAuthorizeResponseMode]; !ok || val == "" {
envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode
// Set the default value to token type
if envData[constants.EnvKeyDefaultAuthorizeResponseMode] == "" {
envData[constants.EnvKeyDefaultAuthorizeResponseMode] = constants.ResponseModeQuery
}
}
if osAuthorizeResponseMode != "" && envData[constants.EnvKeyDefaultAuthorizeResponseMode] != osAuthorizeResponseMode {
envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode
}
err = memorystore.Provider.UpdateEnvStore(envData)
if err != nil {
log.Debug("Error while updating env store: ", err)

View File

@@ -11,16 +11,17 @@ require (
github.com/gin-gonic/gin v1.8.1
github.com/glebarez/sqlite v1.5.0
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/gocql/gocql v1.2.0
github.com/golang-jwt/jwt v3.2.2+incompatible
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/guregu/dynamo v1.16.0
github.com/joho/godotenv v1.3.0
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // 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/sirupsen/logrus v1.8.1
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/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/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/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
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.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
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/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
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.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
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/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
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.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
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/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
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.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
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/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
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/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/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.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
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/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
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/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-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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
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-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-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-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-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-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-20211015210444-4f30a5c0130f/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/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-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-20190312061237-fead79001313/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-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-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-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-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-20191228213918-04cbcbbfeed8/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-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-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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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-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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
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/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/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
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/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
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.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
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.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.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/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -88,6 +88,8 @@ type ComplexityRoot struct {
DatabaseType func(childComplexity int) int
DatabaseURL func(childComplexity int) int
DatabaseUsername func(childComplexity int) int
DefaultAuthorizeResponseMode func(childComplexity int) int
DefaultAuthorizeResponseType func(childComplexity int) int
DefaultRoles func(childComplexity int) int
DisableBasicAuthentication func(childComplexity int) int
DisableEmailVerification func(childComplexity int) int
@@ -126,6 +128,7 @@ type ComplexityRoot struct {
SMTPPort func(childComplexity int) int
SMTPUsername func(childComplexity int) int
SenderEmail func(childComplexity int) int
SenderName func(childComplexity int) int
TwitterClientID func(childComplexity int) int
TwitterClientSecret func(childComplexity int) int
}
@@ -141,6 +144,11 @@ type ComplexityRoot struct {
Secret func(childComplexity int) int
}
InviteMembersResponse struct {
Message func(childComplexity int) int
Users func(childComplexity int) int
}
Meta struct {
ClientID func(childComplexity int) int
IsAppleLoginEnabled func(childComplexity int) int
@@ -327,7 +335,7 @@ type MutationResolver interface {
AdminLogin(ctx context.Context, params model.AdminLoginInput) (*model.Response, error)
AdminLogout(ctx context.Context) (*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)
EnableAccess(ctx context.Context, param model.UpdateAccessInput) (*model.Response, error)
GenerateJwtKeys(ctx context.Context, params model.GenerateJWTKeysInput) (*model.GenerateJWTKeysResponse, error)
@@ -608,6 +616,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Env.DatabaseUsername(childComplexity), true
case "Env.DEFAULT_AUTHORIZE_RESPONSE_MODE":
if e.complexity.Env.DefaultAuthorizeResponseMode == nil {
break
}
return e.complexity.Env.DefaultAuthorizeResponseMode(childComplexity), true
case "Env.DEFAULT_AUTHORIZE_RESPONSE_TYPE":
if e.complexity.Env.DefaultAuthorizeResponseType == nil {
break
}
return e.complexity.Env.DefaultAuthorizeResponseType(childComplexity), true
case "Env.DEFAULT_ROLES":
if e.complexity.Env.DefaultRoles == nil {
break
@@ -874,6 +896,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
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":
if e.complexity.Env.TwitterClientID == nil {
break
@@ -923,6 +952,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
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":
if e.complexity.Meta.ClientID == nil {
break
@@ -2144,6 +2187,11 @@ type Response {
message: String!
}
type InviteMembersResponse {
message: String!
Users: [User!]!
}
type Env {
ACCESS_TOKEN_EXPIRY_TIME: String
ADMIN_SECRET: String
@@ -2163,6 +2211,7 @@ type Env {
SMTP_PASSWORD: String
SMTP_LOCAL_NAME: String
SENDER_EMAIL: String
SENDER_NAME: String
JWT_TYPE: String
JWT_SECRET: String
JWT_PRIVATE_KEY: String
@@ -2203,6 +2252,8 @@ type Env {
ORGANIZATION_LOGO: String
APP_COOKIE_SECURE: Boolean!
ADMIN_COOKIE_SECURE: Boolean!
DEFAULT_AUTHORIZE_RESPONSE_TYPE: String
DEFAULT_AUTHORIZE_RESPONSE_MODE: String
}
type ValidateJWTTokenResponse {
@@ -2278,6 +2329,7 @@ input UpdateEnvInput {
SMTP_PASSWORD: String
SMTP_LOCAL_NAME: String
SENDER_EMAIL: String
SENDER_NAME: String
JWT_TYPE: String
JWT_SECRET: String
JWT_PRIVATE_KEY: String
@@ -2317,6 +2369,8 @@ input UpdateEnvInput {
MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: String
ORGANIZATION_NAME: String
ORGANIZATION_LOGO: String
DEFAULT_AUTHORIZE_RESPONSE_TYPE: String
DEFAULT_AUTHORIZE_RESPONSE_MODE: String
}
input AdminLoginInput {
@@ -2576,7 +2630,8 @@ input ResendOTPRequest {
}
input GetUserRequest {
id: String!
id: String
email: String
}
type Mutation {
@@ -2601,7 +2656,7 @@ type Mutation {
_admin_login(params: AdminLoginInput!): Response!
_admin_logout: Response!
_update_env(params: UpdateEnvInput!): Response!
_invite_members(params: InviteMemberInput!): Response!
_invite_members(params: InviteMemberInput!): InviteMembersResponse!
_revoke_access(param: UpdateAccessInput!): Response!
_enable_access(param: UpdateAccessInput!): Response!
_generate_jwt_keys(params: GenerateJWTKeysInput!): GenerateJWTKeysResponse!
@@ -4751,6 +4806,47 @@ func (ec *executionContext) fieldContext_Env_SENDER_EMAIL(ctx context.Context, f
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) {
fc, err := ec.fieldContext_Env_JWT_TYPE(ctx, field)
if err != nil {
@@ -6424,6 +6520,88 @@ func (ec *executionContext) fieldContext_Env_ADMIN_COOKIE_SECURE(ctx context.Con
return fc, nil
}
func (ec *executionContext) _Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(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.DefaultAuthorizeResponseType, 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_DEFAULT_AUTHORIZE_RESPONSE_TYPE(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_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(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.DefaultAuthorizeResponseMode, 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_DEFAULT_AUTHORIZE_RESPONSE_MODE(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) _Error_message(ctx context.Context, field graphql.CollectedField, obj *model.Error) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Error_message(ctx, field)
if err != nil {
@@ -6635,6 +6813,134 @@ func (ec *executionContext) fieldContext_GenerateJWTKeysResponse_private_key(ctx
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) {
fc, err := ec.fieldContext_Meta_version(ctx, field)
if err != nil {
@@ -8587,9 +8893,9 @@ func (ec *executionContext) _Mutation__invite_members(ctx context.Context, field
}
return graphql.Null
}
res := resTmp.(*model.Response)
res := resTmp.(*model.InviteMembersResponse)
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) {
@@ -8601,9 +8907,11 @@ func (ec *executionContext) fieldContext_Mutation__invite_members(ctx context.Co
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
switch field.Name {
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() {
@@ -10024,6 +10332,8 @@ func (ec *executionContext) fieldContext_Query__env(ctx context.Context, field g
return ec.fieldContext_Env_SMTP_LOCAL_NAME(ctx, field)
case "SENDER_EMAIL":
return ec.fieldContext_Env_SENDER_EMAIL(ctx, field)
case "SENDER_NAME":
return ec.fieldContext_Env_SENDER_NAME(ctx, field)
case "JWT_TYPE":
return ec.fieldContext_Env_JWT_TYPE(ctx, field)
case "JWT_SECRET":
@@ -10104,6 +10414,10 @@ func (ec *executionContext) fieldContext_Query__env(ctx context.Context, field g
return ec.fieldContext_Env_APP_COOKIE_SECURE(ctx, field)
case "ADMIN_COOKIE_SECURE":
return ec.fieldContext_Env_ADMIN_COOKIE_SECURE(ctx, field)
case "DEFAULT_AUTHORIZE_RESPONSE_TYPE":
return ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(ctx, field)
case "DEFAULT_AUTHORIZE_RESPONSE_MODE":
return ec.fieldContext_Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx, field)
}
return nil, fmt.Errorf("no field named %q was found under type Env", field.Name)
},
@@ -15056,7 +15370,7 @@ func (ec *executionContext) unmarshalInputGetUserRequest(ctx context.Context, ob
asMap[k] = v
}
fieldsInOrder := [...]string{"id"}
fieldsInOrder := [...]string{"id", "email"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
@@ -15067,7 +15381,15 @@ func (ec *executionContext) unmarshalInputGetUserRequest(ctx context.Context, ob
var err error
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 {
return it, err
}
@@ -16016,7 +16338,7 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
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"}
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 {
v, ok := asMap[k]
if !ok {
@@ -16103,6 +16425,14 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
if err != nil {
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":
var err error
@@ -16415,6 +16745,22 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
if err != nil {
return it, err
}
case "DEFAULT_AUTHORIZE_RESPONSE_TYPE":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("DEFAULT_AUTHORIZE_RESPONSE_TYPE"))
it.DefaultAuthorizeResponseType, err = ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
case "DEFAULT_AUTHORIZE_RESPONSE_MODE":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("DEFAULT_AUTHORIZE_RESPONSE_MODE"))
it.DefaultAuthorizeResponseMode, err = ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
}
}
@@ -17136,6 +17482,10 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, 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":
out.Values[i] = ec._Env_JWT_TYPE(ctx, field, obj)
@@ -17329,6 +17679,14 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, obj
if out.Values[i] == graphql.Null {
invalids++
}
case "DEFAULT_AUTHORIZE_RESPONSE_TYPE":
out.Values[i] = ec._Env_DEFAULT_AUTHORIZE_RESPONSE_TYPE(ctx, field, obj)
case "DEFAULT_AUTHORIZE_RESPONSE_MODE":
out.Values[i] = ec._Env_DEFAULT_AUTHORIZE_RESPONSE_MODE(ctx, field, obj)
default:
panic("unknown field " + strconv.Quote(field.Name))
}
@@ -17408,6 +17766,41 @@ func (ec *executionContext) _GenerateJWTKeysResponse(ctx context.Context, sel as
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"}
func (ec *executionContext) _Meta(ctx context.Context, sel ast.SelectionSet, obj *model.Meta) graphql.Marshaler {
@@ -19265,6 +19658,20 @@ func (ec *executionContext) unmarshalNInviteMemberInput2githubᚗcomᚋauthorize
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) {
res, err := ec.unmarshalInputLoginInput(ctx, v)
return res, graphql.ErrorOnPath(ctx, err)

View File

@@ -77,6 +77,7 @@ type Env struct {
SMTPPassword *string `json:"SMTP_PASSWORD"`
SMTPLocalName *string `json:"SMTP_LOCAL_NAME"`
SenderEmail *string `json:"SENDER_EMAIL"`
SenderName *string `json:"SENDER_NAME"`
JwtType *string `json:"JWT_TYPE"`
JwtSecret *string `json:"JWT_SECRET"`
JwtPrivateKey *string `json:"JWT_PRIVATE_KEY"`
@@ -117,6 +118,8 @@ type Env struct {
OrganizationLogo *string `json:"ORGANIZATION_LOGO"`
AppCookieSecure bool `json:"APP_COOKIE_SECURE"`
AdminCookieSecure bool `json:"ADMIN_COOKIE_SECURE"`
DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE"`
DefaultAuthorizeResponseMode *string `json:"DEFAULT_AUTHORIZE_RESPONSE_MODE"`
}
type Error struct {
@@ -141,7 +144,8 @@ type GenerateJWTKeysResponse struct {
}
type GetUserRequest struct {
ID string `json:"id"`
ID *string `json:"id"`
Email *string `json:"email"`
}
type InviteMemberInput struct {
@@ -149,6 +153,11 @@ type InviteMemberInput struct {
RedirectURI *string `json:"redirect_uri"`
}
type InviteMembersResponse struct {
Message string `json:"message"`
Users []*User `json:"Users"`
}
type ListWebhookLogRequest struct {
Pagination *PaginationInput `json:"pagination"`
WebhookID *string `json:"webhook_id"`
@@ -314,6 +323,7 @@ type UpdateEnvInput struct {
SMTPPassword *string `json:"SMTP_PASSWORD"`
SMTPLocalName *string `json:"SMTP_LOCAL_NAME"`
SenderEmail *string `json:"SENDER_EMAIL"`
SenderName *string `json:"SENDER_NAME"`
JwtType *string `json:"JWT_TYPE"`
JwtSecret *string `json:"JWT_SECRET"`
JwtPrivateKey *string `json:"JWT_PRIVATE_KEY"`
@@ -353,6 +363,8 @@ type UpdateEnvInput struct {
MicrosoftActiveDirectoryTenantID *string `json:"MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID"`
OrganizationName *string `json:"ORGANIZATION_NAME"`
OrganizationLogo *string `json:"ORGANIZATION_LOGO"`
DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE"`
DefaultAuthorizeResponseMode *string `json:"DEFAULT_AUTHORIZE_RESPONSE_MODE"`
}
type UpdateProfileInput struct {

View File

@@ -94,6 +94,11 @@ type Response {
message: String!
}
type InviteMembersResponse {
message: String!
Users: [User!]!
}
type Env {
ACCESS_TOKEN_EXPIRY_TIME: String
ADMIN_SECRET: String
@@ -113,6 +118,7 @@ type Env {
SMTP_PASSWORD: String
SMTP_LOCAL_NAME: String
SENDER_EMAIL: String
SENDER_NAME: String
JWT_TYPE: String
JWT_SECRET: String
JWT_PRIVATE_KEY: String
@@ -153,6 +159,8 @@ type Env {
ORGANIZATION_LOGO: String
APP_COOKIE_SECURE: Boolean!
ADMIN_COOKIE_SECURE: Boolean!
DEFAULT_AUTHORIZE_RESPONSE_TYPE: String
DEFAULT_AUTHORIZE_RESPONSE_MODE: String
}
type ValidateJWTTokenResponse {
@@ -228,6 +236,7 @@ input UpdateEnvInput {
SMTP_PASSWORD: String
SMTP_LOCAL_NAME: String
SENDER_EMAIL: String
SENDER_NAME: String
JWT_TYPE: String
JWT_SECRET: String
JWT_PRIVATE_KEY: String
@@ -267,6 +276,8 @@ input UpdateEnvInput {
MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: String
ORGANIZATION_NAME: String
ORGANIZATION_LOGO: String
DEFAULT_AUTHORIZE_RESPONSE_TYPE: String
DEFAULT_AUTHORIZE_RESPONSE_MODE: String
}
input AdminLoginInput {
@@ -526,7 +537,8 @@ input ResendOTPRequest {
}
input GetUserRequest {
id: String!
id: String
email: String
}
type Mutation {
@@ -551,7 +563,7 @@ type Mutation {
_admin_login(params: AdminLoginInput!): Response!
_admin_logout: Response!
_update_env(params: UpdateEnvInput!): Response!
_invite_members(params: InviteMemberInput!): Response!
_invite_members(params: InviteMemberInput!): InviteMembersResponse!
_revoke_access(param: UpdateAccessInput!): Response!
_enable_access(param: UpdateAccessInput!): Response!
_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.
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)
}

View File

@@ -83,7 +83,11 @@ func AuthorizeHandler() gin.HandlerFunc {
}
if responseMode == "" {
responseMode = constants.ResponseModeQuery
if val, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultAuthorizeResponseMode); err == nil {
responseType = val
} else {
responseType = constants.ResponseModeQuery
}
}
if redirectURI == "" {
@@ -91,7 +95,11 @@ func AuthorizeHandler() gin.HandlerFunc {
}
if responseType == "" {
responseType = "token"
if val, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultAuthorizeResponseType); err == nil {
responseType = val
} else {
responseType = constants.ResponseTypeToken
}
}
if err := validateAuthorizeRequest(responseType, responseMode, clientID, state, codeChallenge); err != nil {
@@ -186,7 +194,7 @@ func AuthorizeHandler() gin.HandlerFunc {
// rollover the session for security
go memorystore.Provider.DeleteUserSession(sessionKey, claims.Nonce)
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 {
log.Debug("CreateSessionToken failed: ", err)
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
@@ -207,7 +215,7 @@ func AuthorizeHandler() gin.HandlerFunc {
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)
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
return
@@ -263,13 +271,13 @@ func AuthorizeHandler() gin.HandlerFunc {
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)
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
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)
handleResponse(gc, responseMode, loginURL, redirectURI, loginError, http.StatusOK)
return
@@ -297,7 +305,7 @@ func AuthorizeHandler() gin.HandlerFunc {
if authToken.RefreshToken != nil {
res["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 {

View File

@@ -47,7 +47,14 @@ func LogoutHandler() gin.HandlerFunc {
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)
if redirectURL != "" {

View File

@@ -249,12 +249,12 @@ func OAuthCallbackHandler() gin.HandlerFunc {
sessionKey := provider + ":" + user.ID
cookie.SetSession(ctx, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil {
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() {

View File

@@ -247,8 +247,8 @@ func TokenHandler() gin.HandlerFunc {
return
}
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
cookie.SetSession(gc, authToken.FingerPrintHash)
expiresIn := authToken.AccessToken.ExpiresAt - time.Now().Unix()
@@ -266,7 +266,7 @@ func TokenHandler() gin.HandlerFunc {
if authToken.RefreshToken != nil {
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)

View File

@@ -24,21 +24,22 @@ import (
// It verifies email based on JWT token in query string
func VerifyEmailHandler() gin.HandlerFunc {
return func(c *gin.Context) {
redirectURL := strings.TrimSpace(c.Query("redirect_uri"))
errorRes := gin.H{
"error": "invalid_token",
"error": "token is required",
}
tokenInQuery := c.Query("token")
if tokenInQuery == "" {
log.Debug("Token is empty")
c.JSON(400, errorRes)
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return
}
verificationRequest, err := db.Provider.GetVerificationRequestByToken(c, tokenInQuery)
if err != nil {
log.Debug("Error getting verification request: ", err)
errorRes["error_description"] = err.Error()
c.JSON(400, errorRes)
errorRes["error"] = err.Error()
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return
}
@@ -47,23 +48,23 @@ func VerifyEmailHandler() gin.HandlerFunc {
claim, err := token.ParseJWTToken(tokenInQuery)
if err != nil {
log.Debug("Error parsing token: ", err)
errorRes["error_description"] = err.Error()
c.JSON(400, errorRes)
errorRes["error"] = err.Error()
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return
}
if ok, err := token.ValidateJWTClaims(claim, hostname, verificationRequest.Nonce, verificationRequest.Email); !ok || err != nil {
log.Debug("Error validating jwt claims: ", err)
errorRes["error_description"] = err.Error()
c.JSON(400, errorRes)
errorRes["error"] = err.Error()
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return
}
user, err := db.Provider.GetUserByEmail(c, verificationRequest.Email)
if err != nil {
log.Debug("Error getting user: ", err)
errorRes["error_description"] = err.Error()
c.JSON(400, errorRes)
errorRes["error"] = err.Error()
utils.HandleRedirectORJsonResponse(c, http.StatusBadRequest, errorRes, generateRedirectURL(redirectURL, errorRes))
return
}
@@ -79,7 +80,6 @@ func VerifyEmailHandler() gin.HandlerFunc {
db.Provider.DeleteVerificationRequest(c, verificationRequest)
state := strings.TrimSpace(c.Query("state"))
redirectURL := strings.TrimSpace(c.Query("redirect_uri"))
rolesString := strings.TrimSpace(c.Query("roles"))
var roles []string
if rolesString == "" {
@@ -125,8 +125,8 @@ func VerifyEmailHandler() gin.HandlerFunc {
authToken, err := token.CreateAuthToken(c, user, roles, scope, loginMethod, nonce, code)
if err != nil {
log.Debug("Error creating auth token: ", err)
errorRes["error_description"] = err.Error()
c.JSON(500, errorRes)
errorRes["error"] = err.Error()
utils.HandleRedirectORJsonResponse(c, http.StatusInternalServerError, errorRes, generateRedirectURL(redirectURL, errorRes))
return
}
@@ -135,7 +135,7 @@ func VerifyEmailHandler() gin.HandlerFunc {
// if code != "" {
// if err := memorystore.Provider.SetState(code, codeChallenge+"@@"+authToken.FingerPrintHash); err != nil {
// log.Debug("Error setting code state ", err)
// errorRes["error_description"] = err.Error()
// errorRes["error"] = err.Error()
// c.JSON(500, errorRes)
// return
// }
@@ -154,12 +154,12 @@ func VerifyEmailHandler() gin.HandlerFunc {
sessionKey := loginMethod + ":" + user.ID
cookie.SetSession(c, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil {
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 == "" {
@@ -189,3 +189,21 @@ func VerifyEmailHandler() gin.HandlerFunc {
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
func (c *provider) SetUserSession(userId, key, token string) error {
c.sessionStore.Set(userId, key, token)
func (c *provider) SetUserSession(userId, key, token string, expiration int64) error {
c.sessionStore.Set(userId, key, token, expiration)
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
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.
func (c *provider) DeleteAllUserSessions(userId string) error {
namespaces := []string{
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)
}
c.sessionStore.RemoveAll(userId)
return nil
}
// DeleteUserSession deletes the user session from the in-memory store.
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
}

View File

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

View File

@@ -1,73 +1,140 @@
package stores
import (
"fmt"
"sort"
"strings"
"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
type SessionStore struct {
wg sync.WaitGroup
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
func NewSessionStore() *SessionStore {
return &SessionStore{
mutex: sync.Mutex{},
store: make(map[string]map[string]string),
store := &SessionStore{
mutex: sync.Mutex{},
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
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
func (s *SessionStore) Set(key string, subKey, value string) {
func (s *SessionStore) Set(key string, subKey, value string, expiration int64) {
s.mutex.Lock()
defer s.mutex.Unlock()
if _, ok := s.store[key]; !ok {
s.store[key] = make(map[string]string)
k := fmt.Sprintf("%s:%s", key, subKey)
if _, ok := s.store[k]; !ok {
// 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)
}
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[key][subKey] = value
s.store[k] = &SessionEntry{
Value: value,
ExpiresAt: expiration,
}
s.keyIndex[expiration] = k
}
// RemoveAll all values for given key
func (s *SessionStore) RemoveAll(key string) {
s.mutex.Lock()
defer s.mutex.Unlock()
delete(s.store, key)
for k := range s.store {
if strings.Contains(k, key) {
delete(s.store, k)
}
}
}
// Remove value for given key and subkey
func (s *SessionStore) Remove(key, subKey string) {
s.mutex.Lock()
defer s.mutex.Unlock()
if _, ok := s.store[key]; ok {
delete(s.store[key], subKey)
}
}
// 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]
k := fmt.Sprintf("%s:%s", key, subKey)
delete(s.store, k)
}
// RemoveByNamespace to delete session for a given namespace example google,github
func (s *SessionStore) RemoveByNamespace(namespace string) error {
s.mutex.Lock()
defer s.mutex.Unlock()
for key := range s.store {
if strings.Contains(key, namespace+":") {
delete(s.store, key)

View File

@@ -20,6 +20,8 @@ func NewStateStore() *StateStore {
// Get returns the value of the key in state store
func (s *StateStore) Get(key string) string {
s.mutex.Lock()
defer s.mutex.Unlock()
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
type Provider interface {
// SetUserSession sets the user session for given user identifier in form recipe:user_id
SetUserSession(userId, key, token string) error
// GetAllUserSessions returns all the user sessions from the session store
GetAllUserSessions(userId string) (map[string]string, error)
SetUserSession(userId, key, token string, expiration int64) error
// GetUserSession returns the session token for given token
GetUserSession(userId, key string) (string, error)
// DeleteUserSession deletes the user session

View File

@@ -5,7 +5,7 @@ import (
"strings"
"time"
"github.com/go-redis/redis/v8"
"github.com/redis/go-redis/v9"
log "github.com/sirupsen/logrus"
)
@@ -17,10 +17,11 @@ type RedisClient interface {
HMGet(ctx context.Context, key string, fields ...string) *redis.SliceCmd
HSet(ctx context.Context, key string, values ...interface{}) *redis.IntCmd
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
Get(ctx context.Context, key string) *redis.StringCmd
Scan(ctx context.Context, cursor uint64, match string, count int64) *redis.ScanCmd
Keys(ctx context.Context, pattern string) *redis.StringSliceCmd
}
type provider struct {
@@ -31,7 +32,6 @@ type provider struct {
// NewRedisProvider returns a new redis provider
func NewRedisProvider(redisURL string) (*provider, error) {
redisURLHostPortsList := strings.Split(redisURL, ",")
if len(redisURLHostPortsList) > 1 {
opt, err := redis.ParseURL(redisURLHostPortsList[0])
if err != nil {
@@ -70,7 +70,6 @@ func NewRedisProvider(redisURL string) (*provider, error) {
log.Debug("error connecting to redis: ", err)
return nil, err
}
return &provider{
ctx: ctx,
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
import (
"fmt"
"strconv"
"time"
"github.com/authorizerdev/authorizer/server/constants"
log "github.com/sirupsen/logrus"
@@ -15,29 +17,21 @@ var (
)
// SetUserSession sets the user session for given user identifier in form recipe:user_id
func (c *provider) SetUserSession(userId, key, token string) error {
err := c.store.HSet(c.ctx, userId, key, token).Err()
func (c *provider) SetUserSession(userId, key, token string, expiration int64) error {
currentTime := time.Now()
expireTime := time.Unix(expiration, 0)
duration := expireTime.Sub(currentTime)
err := c.store.Set(c.ctx, fmt.Sprintf("%s:%s", userId, key), token, duration).Err()
if err != nil {
log.Debug("Error saving to redis: ", err)
log.Debug("Error saving user session to redis: ", err)
return err
}
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.
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 {
return "", err
}
@@ -46,39 +40,34 @@ func (c *provider) GetUserSession(userId, key string) (string, error) {
// DeleteUserSession deletes the user session from redis store.
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)
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)
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)
return err
// continue
}
return nil
}
// DeleteAllUserSessions deletes all the user session from redis
func (c *provider) DeleteAllUserSessions(userID string) error {
namespaces := []string{
constants.AuthRecipeMethodBasicAuth,
constants.AuthRecipeMethodMagicLinkLogin,
constants.AuthRecipeMethodApple,
constants.AuthRecipeMethodFacebook,
constants.AuthRecipeMethodGithub,
constants.AuthRecipeMethodGoogle,
constants.AuthRecipeMethodLinkedIn,
constants.AuthRecipeMethodTwitter,
constants.AuthRecipeMethodMicrosoft,
res := c.store.Keys(c.ctx, fmt.Sprintf("*%s*", userID))
if res.Err() != nil {
log.Debug("Error getting all user sessions from redis: ", res.Err())
return res.Err()
}
for _, namespace := range namespaces {
err := c.store.Del(c.ctx, namespace+":"+userID).Err()
keys := res.Val()
for _, key := range keys {
err := c.store.Del(c.ctx, key).Err()
if err != nil {
log.Debug("Error deleting all user sessions from redis: ", err)
return err
continue
}
}
return nil
@@ -86,27 +75,19 @@ func (c *provider) DeleteAllUserSessions(userID string) error {
// DeleteSessionForNamespace to delete session for a given namespace example google,github
func (c *provider) DeleteSessionForNamespace(namespace string) error {
var cursor uint64
for {
keys := []string{}
keys, cursor, err := c.store.Scan(c.ctx, cursor, namespace+":*", 0).Result()
res := c.store.Keys(c.ctx, fmt.Sprintf("%s:*", namespace))
if res.Err() != nil {
log.Debug("Error getting all user sessions from redis: ", res.Err())
return res.Err()
}
keys := res.Val()
for _, key := range keys {
err := c.store.Del(c.ctx, key).Err()
if err != nil {
log.Debugf("Error scanning keys for %s namespace: %s", namespace, err.Error())
return err
}
for _, key := range keys {
err := c.store.Del(c.ctx, key).Err()
if err != nil {
log.Debugf("Error deleting sessions for %s namespace: %s", namespace, err.Error())
return err
}
}
if cursor == 0 { // no more keys
break
log.Debug("Error deleting all user sessions from redis: ", err)
continue
}
}
return nil
}

View File

@@ -89,6 +89,9 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
if val, ok := store[constants.EnvKeySenderEmail]; ok {
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 {
res.SMTPLocalName = refs.NewStringRef(val.(string))
}
@@ -168,6 +171,12 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
if val, ok := store[constants.EnvKeyOrganizationLogo]; ok {
res.OrganizationLogo = refs.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyDefaultAuthorizeResponseType]; ok {
res.DefaultAuthorizeResponseType = refs.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyDefaultAuthorizeResponseMode]; ok {
res.DefaultAuthorizeResponseMode = refs.NewStringRef(val.(string))
}
// string slice vars
res.AllowedOrigins = strings.Split(store[constants.EnvKeyAllowedOrigins].(string), ",")

View File

@@ -23,7 +23,7 @@ import (
)
// 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)
if err != nil {
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)),
Users: InvitedUsers,
}, nil
}

View File

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

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{}{
"user": user.ToMap(),
"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)
sessionStoreKey := constants.AuthRecipeMethodMobileBasicAuth + ":" + user.ID
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionStoreKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil {
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() {

View File

@@ -249,12 +249,12 @@ func MobileSignupResolver(ctx context.Context, params *model.MobileSignUpInput)
sessionKey := constants.AuthRecipeMethodMobileBasicAuth + ":" + user.ID
cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil {
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() {

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{}{
"user": user.ToMap(),
"organization": utils.GetOrganization(),
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname),
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, verificationRequest.RedirectURI),
})
res = &model.Response{

View File

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

View File

@@ -91,7 +91,6 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
}
inputRoles := []string{}
if len(params.Roles) > 0 {
// check if roles exists
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{}{
"user": user.ToMap(),
"organization": utils.GetOrganization(),
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname),
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
})
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
cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil {
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() {

View File

@@ -259,7 +259,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
go email.SendEmail([]string{user.Email}, verificationType, map[string]interface{}{
"user": user.ToMap(),
"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{}{
"user": user.ToMap(),
"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 (
"context"
"fmt"
"strings"
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)
return nil, err
}
if !token.IsSuperAdmin(gc) {
log.Debug("Not logged in as super admin.")
return nil, fmt.Errorf("unauthorized")
}
res, err := db.Provider.GetUserByID(ctx, params.ID)
if err != nil {
log.Debug("Failed to get users: ", err)
return nil, err
// Try getting user by ID
if params.ID != nil && strings.Trim(*params.ID, " ") != "" {
res, err := db.Provider.GetUserByID(ctx, *params.ID)
if err != nil {
log.Debug("Failed to get users by ID: ", 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
cookie.SetSession(gc, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
if authToken.RefreshToken != nil {
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
}

View File

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

View File

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

View File

@@ -8,6 +8,7 @@ import (
"github.com/authorizerdev/authorizer/server/crypto"
"github.com/authorizerdev/authorizer/server/graph/model"
"github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/refs"
"github.com/authorizerdev/authorizer/server/resolvers"
"github.com/stretchr/testify/assert"
)
@@ -26,7 +27,7 @@ func userTest(t *testing.T, s TestSetup) {
assert.NotEmpty(t, res.User)
userRes, err := resolvers.UserResolver(ctx, model.GetUserRequest{
ID: res.User.ID,
ID: &res.User.ID,
})
assert.Nil(t, userRes)
assert.NotNil(t, err, "unauthorized")
@@ -36,14 +37,36 @@ func userTest(t *testing.T, s TestSetup) {
h, err := crypto.EncryptPassword(adminSecret)
assert.Nil(t, err)
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{
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.Equal(t, res.User.ID, userRes.ID)
assert.Equal(t, email, userRes.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, "")
assert.NoError(t, err)
assert.NotNil(t, authToken)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeSessionToken+"_"+authToken.FingerPrint, authToken.FingerPrintHash, authToken.SessionTokenExpiresAt)
memorystore.Provider.SetUserSession(sessionKey, constants.TokenTypeAccessToken+"_"+authToken.FingerPrint, authToken.AccessToken.Token, authToken.AccessToken.ExpiresAt)
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) {

View File

@@ -30,11 +30,13 @@ type JWTToken struct {
// Token object to hold the finger print and refresh token information
type Token struct {
FingerPrint string `json:"fingerprint"`
FingerPrintHash string `json:"fingerprint_hash"`
RefreshToken *JWTToken `json:"refresh_token"`
AccessToken *JWTToken `json:"access_token"`
IDToken *JWTToken `json:"id_token"`
FingerPrint string `json:"fingerprint"`
// Session Token
FingerPrintHash string `json:"fingerprint_hash"`
SessionTokenExpiresAt int64 `json:"expires_at"`
RefreshToken *JWTToken `json:"refresh_token"`
AccessToken *JWTToken `json:"access_token"`
IDToken *JWTToken `json:"id_token"`
}
// SessionData
@@ -51,7 +53,7 @@ type SessionData struct {
// 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) {
hostname := parsers.GetHost(gc)
_, fingerPrintHash, err := CreateSessionToken(user, nonce, roles, scope, loginMethod)
_, fingerPrintHash, sessionTokenExpiresAt, err := CreateSessionToken(user, nonce, roles, scope, loginMethod)
if err != nil {
return nil, err
}
@@ -82,10 +84,11 @@ func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, l
}
res := &Token{
FingerPrint: nonce,
FingerPrintHash: fingerPrintHash,
AccessToken: &JWTToken{Token: accessToken, ExpiresAt: accessTokenExpiresAt},
IDToken: &JWTToken{Token: idToken, ExpiresAt: idTokenExpiresAt},
FingerPrint: nonce,
FingerPrintHash: fingerPrintHash,
SessionTokenExpiresAt: sessionTokenExpiresAt,
AccessToken: &JWTToken{Token: accessToken, ExpiresAt: accessTokenExpiresAt},
IDToken: &JWTToken{Token: idToken, ExpiresAt: idTokenExpiresAt},
}
if utils.StringSliceContains(scope, "offline_access") {
@@ -101,7 +104,8 @@ func CreateAuthToken(gc *gin.Context, user models.User, roles, scope []string, l
}
// 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{
Nonce: nonce,
Roles: roles,
@@ -109,15 +113,15 @@ func CreateSessionToken(user models.User, nonce string, roles, scope []string, l
Scope: scope,
LoginMethod: loginMethod,
IssuedAt: time.Now().Unix(),
ExpiresAt: time.Now().AddDate(1, 0, 0).Unix(),
ExpiresAt: expiresAt,
}
fingerPrintBytes, _ := json.Marshal(fingerPrintMap)
fingerPrintHash, err := crypto.EncryptAES(string(fingerPrintBytes))
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

View File

@@ -92,6 +92,6 @@ func GetInviteVerificationURL(verificationURL, token, redirectURI string) string
}
// GetEmailVerificationURL to get url for invite email verification
func GetEmailVerificationURL(token, hostname string) string {
return hostname + "/verify_email?token=" + token
func GetEmailVerificationURL(token, hostname, redirectURI string) string {
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)
}
}