Compare commits

...

138 Commits

Author SHA1 Message Date
Lakhan Samani
734e54db69 Merge pull request #403 from authorizerdev/fix/upgrade-packages
fix: upgrade packages
2023-10-14 18:08:40 +05:30
Lakhan Samani
a3bda429d0 fix: upgrade packages
- fix app_data for cassandra & scylladb
2023-10-14 18:06:29 +05:30
Lakhan Samani
3fba4e4c28 fix: upgrade packages 2023-10-13 10:49:26 +05:30
Lakhan Samani
2a759de311 fix: upgrade packages 2023-10-13 10:48:51 +05:30
Lakhan Samani
e7c4ee5630 Merge pull request #402 from authorizerdev/fix/profile-access
fix: use session / access_token for profile related queries or mutation
2023-10-13 09:09:46 +05:30
Lakhan Samani
6a4568dcf3 fix: use session / access_token for profile related queries or mutation 2023-10-13 08:11:55 +05:30
Lakhan Samani
e941e4834a Merge pull request #401 from authorizerdev/fix/deactivate-acc
Fix calling deactivate acc
2023-10-12 11:49:11 +05:30
Lakhan Samani
f906fb74af Fix calling deactivate acc 2023-10-12 11:48:37 +05:30
Lakhan Samani
7ced811e6e Merge pull request #399 from authorizerdev/feat/deativate-account
Add api to deactivate user account
2023-10-11 00:22:15 +05:30
Lakhan Samani
c1e1ee13f2 Add webhook event to fe 2023-10-11 00:21:58 +05:30
Lakhan Samani
60de61a74e fix webhook for deactiavtion 2023-10-11 00:20:15 +05:30
Lakhan Samani
843bc022fe Add api to deactivate user account 2023-10-11 00:16:53 +05:30
Lakhan Samani
ad41bcf792 Merge pull request #397 from VishwasShashidhar/main
Support macOS arm64 release binaries
2023-09-30 23:54:33 +05:30
Vishwas Shashidhar
ea2596b9ae support darwin-arm64 builds 2023-09-30 23:23:10 +05:30
Lakhan Samani
c8ccb89a67 Merge pull request #391 from team-scaletech/fix/webhook_bug_389
Fix/webhook bug 389
2023-09-13 17:46:55 +05:30
lemonScaletech
9519b53d4e Merge branch 'main' into fix/webhook_bug_389 2023-09-11 11:57:19 +05:30
Anand Kumar Panigrahi
e7cfaf4fbe Merge branch 'authorizerdev:main' into main 2023-09-11 11:55:27 +05:30
Lakhan Samani
0428488dab Merge pull request #393 from Juneezee/refactor/redundant-nil-check
refactor(server/utils): remove redundant nil check
2023-09-11 11:42:58 +05:30
Eng Zer Jun
f3b672a4cf refactor(server/utils): remove redundant nil check
From the Go specification:

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

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

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

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2023-09-09 12:57:20 +08:00
Lakhan Samani
1d6f569f92 fix: default value for disable playground 2023-09-09 07:11:13 +05:30
Lakhan Samani
fbdc24f314 Merge pull request #390 from team-scaletech/feat/disable_playground
feat: disable playground for non admin
2023-09-08 21:57:57 +05:30
Anand Kumar Panigrahi
1275644abe Merge branch 'authorizerdev:main' into main 2023-09-06 11:30:06 +05:30
Lakhan Samani
ac6b08c093 Merge pull request #392 from imchairmanm/feat/add_koyeb_button
Add button to deploy to Koyeb
2023-09-03 21:11:46 +05:30
Justin Ellingwood
fe461b675b Add button to deploy to Koyeb 2023-09-01 13:30:44 +01:00
lemonScaletech
77e219d990 fix:
* #389 resolved
* typo fixed
2023-08-29 18:14:48 +05:30
lemonScaletech
3ea13d7e93 refactor:
* added blank line eof .env.sample
2023-08-29 12:19:16 +05:30
lemonScaletech
940a09d172 Merge remote-tracking branch 'origin/feat/disable_playground' into feat/disable_playground
# Conflicts:
#	app/yarn.lock
#	server/constants/env.go
#	server/env/env.go
#	server/env/persist_env.go
#	server/memorystore/providers/redis/store.go
2023-08-29 12:00:24 +05:30
lemonScaletech
3ac6875f87 feat:
* resolved conflicts
2023-08-29 11:55:27 +05:30
lemonScaletech
937506ff64 Merge branch 'main' into feat/disable_playground
# Conflicts:
#	app/yarn.lock
#	dashboard/yarn.lock
#	server/constants/env.go
#	server/env/env.go
#	server/env/persist_env.go
#	server/graph/model/models_gen.go
#	server/memorystore/providers/redis/store.go
2023-08-29 11:44:07 +05:30
lemonScaletech
9795ba9097 feat:
* added disable playground functionality
 * added toggle button for playground in dashboard
2023-08-29 11:36:18 +05:30
vipul patel
11dbe9d97a Merge pull request #1 from authorizerdev/main
Authorizer to foke authorizer
2023-08-29 09:15:53 +05:30
lemonScaletech
c9b8bbc3e1 feat:
* added disable playground functionality
 * added toggle button for playground in dashboard
2023-08-28 19:51:42 +05:30
Lakhan Samani
a124edfaee Add user to validate_session
Resolves #379
2023-08-19 20:45:20 +05:30
Lakhan Samani
5e6b033024 fix microsoft active directory config 2023-08-17 14:20:31 +05:30
Lakhan Samani
171d4e3fff remove unused code 2023-08-14 14:16:54 +05:30
Lakhan Samani
cf96a0087f Fix tests for verifying otp using mfa session 2023-08-14 14:15:52 +05:30
Lakhan Samani
09cfad9c27 Merge pull request #382 from authorizerdev/feat-add-field-for-app-data
Add app_data
2023-08-14 12:05:58 +05:30
Lakhan Samani
35e563ab3b Add app_data 2023-08-14 12:01:37 +05:30
Lakhan Samani
e625ed9633 allow common tenant for microsoft 2023-08-03 14:43:27 +05:30
Lakhan Samani
a042c202a0 fix microsoft active directory config 2023-08-03 13:29:07 +05:30
Lakhan Samani
7a76b783b1 Merge pull request #372 from catusax/main
feat: add mfa session to secure otp login
2023-08-03 12:34:39 +05:30
Lakhan Samani
e5400bc7bd fix microsoft active directory config 2023-08-03 12:33:20 +05:30
Lakhan Samani
a8503666e3 fix: add events for signup 2023-08-02 10:02:41 +05:30
Lakhan Samani
b028be3cbc Merge pull request #377 from authorizerdev/fix-webhook-test-endpoint
fix: test webhook endpoint mutation
2023-08-02 00:04:55 +05:30
Lakhan Samani
9a8d20b698 fix: test webhook endpoint mutation
Resolves #376
2023-08-02 00:04:07 +05:30
Lakhan Samani
fab3c2f87e Merge pull request #375 from authorizerdev/fix-db-refs
Fix db refs
2023-08-01 23:38:00 +05:30
Lakhan Samani
3fefcfcd9a fix: refs for dynamo db 2023-08-01 17:37:34 +05:30
Lakhan Samani
c2defdbaac fix: refs for cassandra db 2023-08-01 16:09:17 +05:30
Lakhan Samani
15a4be5431 fix: refs for db provider and few utils 2023-07-31 16:42:11 +05:30
Lakhan Samani
146561bacb fix: allow multi tenant for microsooft 2023-07-25 11:45:08 +05:30
catusax
0c334856bc Merge branch 'main' into main 2023-07-24 14:04:26 +08:00
catusax
ba0cf189de userid ass mfa session key 2023-07-24 12:00:30 +08:00
Lakhan Samani
9f52c08883 [app] bump authorizer-react 1.1.13 2023-07-24 11:56:56 +08:00
Lakhan Samani
80f3698f06 [app] bump authorizer-react 1.1.12 2023-07-24 11:56:56 +08:00
Lakhan Samani
2a2b7abc08 Add optional show_mobile_otp_screen 2023-07-24 11:56:56 +08:00
Lakhan Samani
27e3ed82e4 Update resend otp 2023-07-24 11:56:55 +08:00
Lakhan Samani
6077702626 fix: tests for otp refactor 2023-07-24 11:56:55 +08:00
Lakhan Samani
cf54fcef03 Fix tests 2023-07-24 11:56:55 +08:00
Lakhan Samani
2f849b8f0c Refactor code for otp 2023-07-24 11:56:55 +08:00
Lakhan Samani
85ca0f09bf [draft] Move sms verificaiton to otp models 2023-07-24 11:55:26 +08:00
Lakhan Samani
2fc438d810 [app] bump authorizer-react 1.1.13 2023-07-23 16:13:40 +05:30
Lakhan Samani
1796cace15 [app] bump authorizer-react 1.1.12 2023-07-23 11:30:43 +05:30
Lakhan Samani
43fdc826c4 Add optional show_mobile_otp_screen 2023-07-23 11:23:24 +05:30
catusax
e7652db89c add comments 2023-07-23 13:02:14 +08:00
Lakhan Samani
c80b0d7028 Merge pull request #368 from authorizerdev/fix-sms-verification-for-alldb
Move sms verificaiton to otp models
2023-07-23 10:04:18 +05:30
Lakhan Samani
55fc4b2608 Update resend otp 2023-07-23 10:03:37 +05:30
Lakhan Samani
fac333e195 fix: tests for otp refactor 2023-07-23 07:29:29 +05:30
catusax
5018462559 feat: add mfa session to secure otp login 2023-07-20 15:11:39 +08:00
Lakhan Samani
edb5412c17 Fix tests 2023-07-18 22:50:23 +05:30
Lakhan Samani
87a962504f Increase timeout for redis 2023-07-16 22:57:56 +05:30
Lakhan Samani
d04f79557a Refactor code for otp 2023-07-13 11:39:22 +05:30
Lakhan Samani
c20e9b810a Merge branch 'main' of https://github.com/authorizerdev/authorizer into fix-sms-verification-for-alldb 2023-07-12 22:16:07 +05:30
Lakhan Samani
8d145bd5fe Merge pull request #369 from authorizerdev/feat-add-validate-cookie-api
feat: add resolver to validate browser session
2023-07-12 22:13:47 +05:30
Lakhan Samani
6fa0ad1809 feat: add resolver to validate browser session 2023-07-12 22:12:17 +05:30
Lakhan Samani
abe809ca68 [draft] Move sms verificaiton to otp models 2023-07-12 11:24:13 +05:30
Lakhan Samani
07f71e883b Add comments for twillio 2023-07-11 14:49:16 +05:30
Lakhan Samani
6cef9064c3 Update provider template for sms verification 2023-07-11 14:48:37 +05:30
Lakhan Samani
9ae616b6b5 Merge pull request #365 from JokerQyou/patch-1
Fix wrong response_type parsed when missing response_mode
2023-06-30 18:10:31 +05:30
Joker_
356428ea02 Fix wrong response_type parsed when missing response_mode 2023-06-29 23:10:44 +08:00
Lakhan Samani
7f47177741 Merge pull request #359 from MussieT/feat/sms_confirmation
Feat/sms confirmation
2023-06-13 09:38:23 +05:30
Mussie Teshome
9fb00544cd removed unwanted comment 2023-06-11 20:44:09 +03:00
Mussie Teshome
2b022d1058 Fix typo 2023-06-11 16:23:31 +03:00
Mussie Teshome
1c84d9f4a8 Merge branch 'authorizerdev:main' into feat/sms_confirmation 2023-06-11 16:05:29 +03:00
Mussie Teshome
0838b60fae Added VerifyMobileTest to the resolver 2023-06-11 16:03:16 +03:00
Mussie Teshome
325134466d Testing verify_mobile resolver 2023-06-11 16:02:46 +03:00
Mussie Teshome
58d9978dd5 Updated to test verification 2023-06-11 16:01:49 +03:00
Mussie Teshome
801d64e2f5 Twilio configuration 2023-06-11 16:00:30 +03:00
Mussie Teshome
dd3cc9de3a Verify mobile resolver 2023-06-11 16:00:07 +03:00
Mussie Teshome
8dc7366182 Updated mobile signup to send sms when service enabled 2023-06-11 15:59:53 +03:00
Mussie Teshome
7749534087 generated 2023-06-11 15:59:18 +03:00
Mussie Teshome
510f16e7b0 New resolver - Verify Moblie 2023-06-11 15:59:03 +03:00
Mussie Teshome
d5e83ea14f Schema update for SMSVerificationRequest 2023-06-11 15:58:50 +03:00
Mussie Teshome
b4a90de1d4 Updated to support disable sms verification request 2023-06-11 15:58:04 +03:00
Mussie Teshome
c525ad92f2 SQL Related dbs CRUD implementation for SMS 2023-06-11 15:57:14 +03:00
Mussie Teshome
9028682e93 Added SMSVerificationRequests model to automigrate 2023-06-11 15:56:40 +03:00
Mussie Teshome
3d6bfe4480 mongo implementation for the sms crud 2023-06-11 15:56:02 +03:00
Mussie Teshome
043af08bf0 Mongo collection for SMSVerificationRequest model 2023-06-11 15:55:11 +03:00
Mussie Teshome
0af78479fc Different dbs fn skeleton which fn yet not written 2023-06-11 15:54:23 +03:00
Mussie Teshome
096f686495 Added delete sms request to the interface 2023-06-11 15:52:33 +03:00
Mussie Teshome
c574c6a679 configure twilio via environment variables 2023-06-11 15:52:07 +03:00
Mussie Teshome
6428b74e64 twilio - new package 2023-06-11 15:50:09 +03:00
Mussie Teshome
aa3892025d New resolvers for sms requests 2023-06-11 15:49:25 +03:00
Mussie Teshome
b2f3d6eb80 sms verification requests model 2023-06-08 11:53:06 +03:00
Mussie Teshome
348cbf8c38 Add sms verification to collection 2023-06-08 11:52:39 +03:00
Mussie Teshome
8ac33a085c commented out sms twilio sender 2023-06-01 15:29:22 +03:00
Lakhan Samani
6c9b359081 Merge pull request #355 from minilikmila/fix/facebook-login
Modify the Facebook login authentication callback to enable user email access through the response body.
2023-05-29 10:32:27 +05:30
Mila Shumete
0fde46d274 setting on facebook user email method --- change the parameter(key) passed to get the email from map 2023-05-28 17:10:29 +03:00
Lakhan Samani
1a5b446894 Merge pull request #353 from authorizerdev/add-get-user-by-email
[server] add ability to get user by email
2023-05-20 09:50:59 +05:30
Lakhan Samani
930c934fdb [server] add ability to get user by email 2023-05-20 09:49:18 +05:30
Lakhan Samani
4e7074d75b Merge pull request #351 from miqe/feat/add_sender_name
Feat/add sender name
2023-05-16 14:07:18 +05:30
Michael Sahlu
bdfa045a43 add SENDER_NAME env 2023-05-16 00:59:45 +03:00
Michael Sahlu
a258399bde add Sender Name input 2023-05-16 00:59:01 +03:00
Michael Sahlu
55a25436a8 add SENDER_NAME in env variable query 2023-05-16 00:58:26 +03:00
Michael Sahlu
9fa402f5c8 add SENDER_NAME environment and types 2023-05-16 00:57:33 +03:00
Michael Sahlu
1111729ad4 add sender name / from name 2023-05-16 00:51:28 +03:00
Michael Sahlu
e56c2f58e5 add sender name on schema and resolver 2023-05-16 00:46:22 +03:00
Michael Sahlu
8dbd2556eb retrive sender name from env 2023-05-16 00:40:14 +03:00
Michael Sahlu
17bb077f3e add EnvKeySenderName for SENDER_NAME env variable 2023-05-16 00:39:25 +03:00
Lakhan Samani
f291417378 Merge pull request #350 from authorizerdev/fix/redirect-uri-error
[server]fix: error redirection for email verification
2023-05-12 16:43:38 +05:30
Lakhan Samani
f831379d27 revert change for forgot password 2023-05-12 16:39:02 +05:30
Lakhan Samani
a50f6becbd [server]fix: error redirection for email verification 2023-05-02 18:39:10 +05:30
Lakhan Samani
a6f6e0b18a Merge pull request #349 from darshvaghela/main 2023-04-24 09:32:38 +05:30
darshvaghela
3868157e11 refactored code 2023-04-23 17:31:24 +05:30
darshvaghela
d693c05483 Features enhancement (Disable/Enable) 2023-04-22 15:21:47 +05:30
Lakhan Samani
6f1fbf886d Merge pull request #346 from MussieT/feat/return-user-info-on-invitation
Feat/return user info on invitation
2023-04-20 13:59:49 +05:30
Mussie Teshome
b86487fda4 assert message and response is not null 2023-04-20 10:43:06 +03:00
Mussie Teshome
28d4ddeb50 Return the new emails only 2023-04-19 15:38:30 +03:00
Mussie Teshome
b9ab1d3761 return err on err 2023-04-19 15:31:57 +03:00
Mussie Teshome
a5b643e127 removed unnecessary comment 2023-04-19 15:19:17 +03:00
Mussie Teshome
691664e629 Invite members resolver updated to return user info 2023-04-19 14:46:27 +03:00
Mussie Teshome
efb67a9538 New response type for invite members 2023-04-19 14:45:22 +03:00
Mussie Teshome
a0f2eeba3e golang package updates 2023-04-19 14:44:50 +03:00
Mussie Teshome
d1a0ccd790 package updates while running make clean && make 2023-04-19 14:44:17 +03:00
Lakhan Samani
729c23f578 [chore]: update authorizer-react 2023-04-15 14:14:47 +05:30
Lakhan Samani
a074f85391 [chore]: update contributing guide 2023-04-15 08:33:33 +05:30
Lakhan Samani
4e7ec6cb7b [chore]: add command to generate db template 2023-04-15 08:13:10 +05:30
Lakhan Samani
6d541cbfb9 fix: use normal mutex for cache 2023-04-10 15:33:59 +05:30
Lakhan Samani
1ebba7f2b7 Merge pull request #343 from authorizerdev/fix/session-storage
fix: session storage
2023-04-08 18:07:52 +05:30
172 changed files with 8802 additions and 3721 deletions

View File

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

View File

@@ -7,4 +7,9 @@ SMTP_PORT=2525
SMTP_USERNAME=test
SMTP_PASSWORD=test
SENDER_EMAIL="info@authorizer.dev"
TWILIO_API_KEY=test
TWILIO_API_SECRET=test
TWILIO_ACCOUNT_SID=ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
TWILIO_SENDER=909921212112
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

View File

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

1
.gitignore vendored
View File

@@ -18,3 +18,4 @@ yalc.lock
certs/
*-shm
*-wal
.idea

View File

@@ -1,4 +1,4 @@
FROM golang:1.19.5-alpine as go-builder
FROM golang:1.21.3-alpine3.18 as go-builder
WORKDIR /authorizer
COPY server server
COPY Makefile .
@@ -11,7 +11,7 @@ RUN apk add build-base &&\
make clean && make && \
chmod 777 build/server
FROM node:17-alpine3.12 as node-builder
FROM node:20-alpine3.18 as node-builder
WORKDIR /authorizer
COPY app app
COPY dashboard dashboard
@@ -20,7 +20,7 @@ RUN apk add build-base &&\
make build-app && \
make build-dashboard
FROM alpine:latest
FROM alpine:3.18
RUN adduser -D -h /authorizer -u 1000 -k /dev/null authorizer
WORKDIR /authorizer
RUN mkdir app dashboard

View File

@@ -5,7 +5,7 @@ cmd:
cd server && go build -ldflags "-w -X main.VERSION=$(VERSION)" -o '../build/server'
build:
cd server && gox \
-osarch="linux/amd64 linux/arm64 darwin/amd64 windows/amd64" \
-osarch="linux/amd64 linux/arm64 darwin/arm64 darwin/amd64 windows/amd64" \
-ldflags "-w -X main.VERSION=$(VERSION)" \
-output="../build/{{.OS}}/{{.Arch}}/server" \
./...
@@ -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' {} \;

View File

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

63
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.13",
"@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.6",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz",
"integrity": "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==",
"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.13",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz",
"integrity": "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==",
"dependencies": {
"@authorizerdev/authorizer-js": "^1.1.4"
"@authorizerdev/authorizer-js": "^1.2.6"
},
"engines": {
"node": ">=10"
@@ -403,11 +406,11 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"node_modules/cross-fetch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
"integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==",
"dependencies": {
"node-fetch": "2.6.7"
"node-fetch": "^2.6.12"
}
},
"node_modules/css-color-keywords": {
@@ -564,9 +567,9 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
@@ -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.6",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz",
"integrity": "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==",
"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.13",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz",
"integrity": "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==",
"requires": {
"@authorizerdev/authorizer-js": "^1.1.4"
"@authorizerdev/authorizer-js": "^1.2.6"
}
},
"@babel/code-frame": {
@@ -1141,11 +1144,11 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"cross-fetch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
"integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==",
"requires": {
"node-fetch": "2.6.7"
"node-fetch": "^2.6.12"
}
},
"css-color-keywords": {
@@ -1267,9 +1270,9 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node-fetch": {
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
"requires": {
"whatwg-url": "^5.0.0"
}

View File

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

View File

@@ -2,19 +2,19 @@
# 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.6":
version "1.2.6"
resolved "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz"
integrity sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==
dependencies:
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.13":
version "1.1.13"
resolved "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz"
integrity sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==
dependencies:
"@authorizerdev/authorizer-js" "^1.1.4"
"@authorizerdev/authorizer-js" "^1.2.6"
"@babel/code-frame@^7.16.7":
version "7.16.7"
@@ -278,11 +278,11 @@ color-name@1.1.3:
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
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==
version "3.1.8"
resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz"
integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==
dependencies:
node-fetch "2.6.7"
node-fetch "^2.6.12"
css-color-keywords@^1.0.0:
version "1.0.0"
@@ -389,10 +389,10 @@ ms@2.1.2:
resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
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.12:
version "2.6.12"
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz"
integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==
dependencies:
whatwg-url "^5.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">
@@ -125,6 +124,19 @@ const Features = ({ variables, setVariables }: any) => {
/>
</Flex>
</Flex>
<Flex>
<Flex w="100%" justifyContent="start" alignItems="center">
<Text fontSize="sm">Playground:</Text>
</Flex>
<Flex justifyContent="start">
<InputField
variables={variables}
setVariables={setVariables}
inputType={SwitchInputType.DISABLE_PLAYGROUND}
hasReversedValue
/>
</Flex>
</Flex>
</Stack>
<Divider paddingY={5} />
<Text fontSize="md" paddingTop={5} fontWeight="bold" mb={5}>

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',
@@ -83,6 +84,7 @@ export const SwitchInputType = {
DISABLE_STRONG_PASSWORD: 'DISABLE_STRONG_PASSWORD',
DISABLE_MULTI_FACTOR_AUTHENTICATION: 'DISABLE_MULTI_FACTOR_AUTHENTICATION',
ENFORCE_MULTI_FACTOR_AUTHENTICATION: 'ENFORCE_MULTI_FACTOR_AUTHENTICATION',
DISABLE_PLAYGROUND: 'DISABLE_PLAYGROUND',
};
export const DateInputType = {
@@ -143,6 +145,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;
@@ -165,6 +168,7 @@ export interface envVarTypes {
ENFORCE_MULTI_FACTOR_AUTHENTICATION: boolean;
DEFAULT_AUTHORIZE_RESPONSE_TYPE: string;
DEFAULT_AUTHORIZE_RESPONSE_MODE: string;
DISABLE_PLAYGROUND: boolean;
}
export const envSubViews = {
@@ -218,6 +222,7 @@ export const webhookEventNames = {
'User deleted': 'user.deleted',
'User access enabled': 'user.access_enabled',
'User access revoked': 'user.access_revoked',
'User deactivated': 'user.deactivated',
};
export const emailTemplateEventNames = {

View File

@@ -50,6 +50,7 @@ export const EnvVariablesQuery = `
SMTP_PASSWORD
SMTP_LOCAL_NAME
SENDER_EMAIL
SENDER_NAME
ALLOWED_ORIGINS
ORGANIZATION_NAME
ORGANIZATION_LOGO
@@ -72,6 +73,7 @@ export const EnvVariablesQuery = `
ENFORCE_MULTI_FACTOR_AUTHENTICATION
DEFAULT_AUTHORIZE_RESPONSE_TYPE
DEFAULT_AUTHORIZE_RESPONSE_MODE
DISABLE_PLAYGROUND
}
}
`;

View File

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

View File

@@ -118,7 +118,6 @@ const Webhooks = () => {
useEffect(() => {
fetchWebookData();
}, [paginationProps.page, paginationProps.limit]);
console.log({ webhookData });
return (
<Box m="5" py="5" px="10" bg="white" rounded="md">
<Flex margin="2% 0" justifyContent="space-between" alignItems="center">

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,8 @@ const (
AuthRecipeMethodMobileBasicAuth = "mobile_basic_auth"
// AuthRecipeMethodMagicLinkLogin is the magic_link_login auth method
AuthRecipeMethodMagicLinkLogin = "magic_link_login"
// AuthRecipeMethodMobileOTP is the mobile_otp auth method
AuthRecipeMethodMobileOTP = "mobile_otp"
// AuthRecipeMethodGoogle is the google auth method
AuthRecipeMethodGoogle = "google"
// AuthRecipeMethodGithub is the github auth method

View File

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

View File

@@ -62,8 +62,12 @@ 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"
// EnvKeyIsSMSServiceEnabled key for env variable IS_SMS_SERVICE_ENABLED
EnvKeyIsSMSServiceEnabled = "IS_SMS_SERVICE_ENABLED"
// EnvKeyAppCookieSecure key for env variable APP_COOKIE_SECURE
EnvKeyAppCookieSecure = "APP_COOKIE_SECURE"
// EnvKeyAdminCookieSecure key for env variable ADMIN_COOKIE_SECURE
@@ -156,6 +160,12 @@ const (
// EnvKeyDisableMultiFactorAuthentication is key for env variable DISABLE_MULTI_FACTOR_AUTHENTICATION
// this variable is used to completely disable multi factor authentication. It will have no effect on profile preference
EnvKeyDisableMultiFactorAuthentication = "DISABLE_MULTI_FACTOR_AUTHENTICATION"
// EnvKeyDisablePhoneVerification is key for env variable DISABLE_PHONE_VERIFICATION
// this variable is used to disable phone verification
EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION"
// EnvKeyDisablePlayGround is key for env variable DISABLE_PLAYGROUND
// this variable will disable or enable playground use in dashboard
EnvKeyDisablePlayGround = "DISABLE_PLAYGROUND"
// Slice variables
// EnvKeyRoles key for env variable ROLES
@@ -174,4 +184,14 @@ const (
// 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"
// Twilio env variables
// EnvKeyTwilioAPIKey key for env variable TWILIO_API_KEY
EnvKeyTwilioAPIKey = "TWILIO_API_KEY"
// EnvKeyTwilioAPISecret key for env variable TWILIO_API_SECRET
EnvKeyTwilioAPISecret = "TWILIO_API_SECRET"
// EnvKeyTwilioAccountSID key for env variable TWILIO_ACCOUNT_SID
EnvKeyTwilioAccountSID = "TWILIO_ACCOUNT_SID"
// EnvKeyTwilioSender key for env variable TWILIO_SENDER
EnvKeyTwilioSender = "TWILIO_SENDER"
)

View File

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

View File

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

View File

@@ -10,6 +10,7 @@ type CollectionList struct {
WebhookLog string
EmailTemplate string
OTP string
SMSVerificationRequest string
}
var (
@@ -25,5 +26,6 @@ var (
WebhookLog: Prefix + "webhook_logs",
EmailTemplate: Prefix + "email_templates",
OTP: Prefix + "otps",
SMSVerificationRequest: Prefix + "sms_verification_requests",
}
)

View File

@@ -1,10 +1,18 @@
package models
const (
// FieldName email is the field name for email
FieldNameEmail = "email"
// FieldNamePhoneNumber is the field name for phone number
FieldNamePhoneNumber = "phone_number"
)
// OTP model for database
type OTP struct {
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,hash"`
PhoneNumber string `gorm:"index:unique_index_phone_number,unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number"`
Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"`
ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"`
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`

View File

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

View File

@@ -12,16 +12,14 @@ import (
)
// AddEmailTemplate to add EmailTemplate
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
emailTemplate.Key = emailTemplate.ID
}
emailTemplate.Key = emailTemplate.ID
emailTemplate.CreatedAt = time.Now().Unix()
emailTemplate.UpdatedAt = time.Now().Unix()
emailTemplateCollection, _ := p.db.Collection(ctx, models.Collections.EmailTemplate)
_, err := emailTemplateCollection.CreateDocument(ctx, emailTemplate)
if err != nil {
@@ -31,74 +29,63 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em
}
// UpdateEmailTemplate to update EmailTemplate
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
emailTemplate.UpdatedAt = time.Now().Unix()
emailTemplateCollection, _ := p.db.Collection(ctx, models.Collections.EmailTemplate)
meta, err := emailTemplateCollection.UpdateDocument(ctx, emailTemplate.Key, emailTemplate)
if err != nil {
return nil, err
}
emailTemplate.Key = meta.Key
emailTemplate.ID = meta.ID.String()
return emailTemplate.AsAPIEmailTemplate(), nil
}
// ListEmailTemplates to list EmailTemplate
func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) {
func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
emailTemplates := []*model.EmailTemplate{}
query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.EmailTemplate, pagination.Offset, pagination.Limit)
sctx := arangoDriver.WithQueryFullCount(ctx)
cursor, err := p.db.Query(sctx, query, nil)
if err != nil {
return nil, err
}
defer cursor.Close()
paginationClone := pagination
paginationClone.Total = cursor.Statistics().FullCount()
for {
var emailTemplate models.EmailTemplate
var emailTemplate *models.EmailTemplate
meta, err := cursor.ReadDocument(ctx, &emailTemplate)
if arangoDriver.IsNoMoreDocuments(err) {
break
} else if err != nil {
return nil, err
}
if meta.Key != "" {
emailTemplates = append(emailTemplates, emailTemplate.AsAPIEmailTemplate())
}
}
return &model.EmailTemplates{
Pagination: &paginationClone,
Pagination: paginationClone,
EmailTemplates: emailTemplates,
}, nil
}
// GetEmailTemplateByID to get EmailTemplate by id
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate
var emailTemplate *models.EmailTemplate
query := fmt.Sprintf("FOR d in %s FILTER d._key == @email_template_id RETURN d", models.Collections.EmailTemplate)
bindVars := map[string]interface{}{
"email_template_id": emailTemplateID,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
return nil, err
}
defer cursor.Close()
for {
if !cursor.HasMore() {
if emailTemplate.Key == "" {
if emailTemplate == nil {
return nil, fmt.Errorf("email template not found")
}
break
@@ -113,21 +100,19 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str
// GetEmailTemplateByEventName to get EmailTemplate by event_name
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate
var emailTemplate *models.EmailTemplate
query := fmt.Sprintf("FOR d in %s FILTER d.event_name == @event_name RETURN d", models.Collections.EmailTemplate)
bindVars := map[string]interface{}{
"event_name": eventName,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
return nil, err
}
defer cursor.Close()
for {
if !cursor.HasMore() {
if emailTemplate.Key == "" {
if emailTemplate == nil {
return nil, fmt.Errorf("email template not found")
}
break

View File

@@ -12,7 +12,7 @@ import (
)
// AddEnv to save environment information in database
func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
env.Key = env.ID
@@ -31,7 +31,7 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro
}
// UpdateEnv to update environment information in database
func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
env.UpdatedAt = time.Now().Unix()
collection, _ := p.db.Collection(ctx, models.Collections.Env)
meta, err := collection.UpdateDocument(ctx, env.Key, env)
@@ -45,19 +45,17 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e
}
// GetEnv to get environment information from database
func (p *provider) GetEnv(ctx context.Context) (models.Env, error) {
var env models.Env
func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
var env *models.Env
query := fmt.Sprintf("FOR d in %s RETURN d", models.Collections.Env)
cursor, err := p.db.Query(ctx, query, nil)
if err != nil {
return env, err
}
defer cursor.Close()
for {
if !cursor.HasMore() {
if env.Key == "" {
if env == nil {
return env, fmt.Errorf("config not found")
}
break

View File

@@ -2,6 +2,7 @@ package arangodb
import (
"context"
"errors"
"fmt"
"time"
@@ -12,7 +13,20 @@ import (
// UpsertOTP to add or update otp
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
otp, _ := p.GetOTPByEmail(ctx, otpParam.Email)
// check if email or phone number is present
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
uniqueField := models.FieldNameEmail
if otpParam.Email == "" && otpParam.PhoneNumber != "" {
uniqueField = models.FieldNamePhoneNumber
}
var otp *models.OTP
if uniqueField == models.FieldNameEmail {
otp, _ = p.GetOTPByEmail(ctx, otpParam.Email)
} else {
otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber)
}
shouldCreate := false
if otp == nil {
id := uuid.NewString()
@@ -21,6 +35,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
Key: id,
Otp: otpParam.Otp,
Email: otpParam.Email,
PhoneNumber: otpParam.PhoneNumber,
ExpiresAt: otpParam.ExpiresAt,
CreatedAt: time.Now().Unix(),
}
@@ -29,10 +44,8 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
otp.Otp = otpParam.Otp
otp.ExpiresAt = otpParam.ExpiresAt
}
otp.UpdatedAt = time.Now().Unix()
otpCollection, _ := p.db.Collection(ctx, models.Collections.OTP)
var meta driver.DocumentMeta
var err error
if shouldCreate {
@@ -40,11 +53,9 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
} else {
meta, err = otpCollection.UpdateDocument(ctx, otp.Key, otp)
}
if err != nil {
return nil, err
}
otp.Key = meta.Key
otp.ID = meta.ID.String()
return otp, nil
@@ -52,22 +63,20 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
// GetOTPByEmail to get otp for a given email address
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
var otp models.OTP
var otp *models.OTP
query := fmt.Sprintf("FOR d in %s FILTER d.email == @email RETURN d", models.Collections.OTP)
bindVars := map[string]interface{}{
"email": emailAddress,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
return nil, err
}
defer cursor.Close()
for {
if !cursor.HasMore() {
if otp.Key == "" {
return nil, fmt.Errorf("email template not found")
if otp == nil {
return nil, fmt.Errorf("otp with given email not found")
}
break
}
@@ -76,8 +85,34 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
return nil, err
}
}
return otp, nil
}
return &otp, nil
// GetOTPByPhoneNumber to get otp for a given phone number
func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
var otp *models.OTP
query := fmt.Sprintf("FOR d in %s FILTER d.phone_number == @phone_number RETURN d", models.Collections.OTP)
bindVars := map[string]interface{}{
"phone_number": phoneNumber,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
return nil, err
}
defer cursor.Close()
for {
if !cursor.HasMore() {
if otp == nil {
return nil, fmt.Errorf("otp with given phone_number not found")
}
break
}
_, err := cursor.ReadDocument(ctx, &otp)
if err != nil {
return nil, err
}
}
return otp, nil
}
// DeleteOTP to delete otp
@@ -87,6 +122,5 @@ func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
if err != nil {
return err
}
return nil
}

View File

@@ -61,7 +61,6 @@ func NewProvider() (*provider, error) {
if err != nil {
return nil, err
}
var arangodb arangoDriver.Database
dbName := memorystore.RequiredEnvStoreObj.GetRequiredEnv().DatabaseName
arangodb_exists, err := arangoClient.DatabaseExists(ctx, dbName)
@@ -79,7 +78,6 @@ func NewProvider() (*provider, error) {
return nil, err
}
}
userCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.User)
if err != nil {
return nil, err
@@ -113,7 +111,6 @@ func NewProvider() (*provider, error) {
return nil, err
}
}
verificationRequestCollection, err := arangodb.Collection(ctx, models.Collections.VerificationRequest)
if err != nil {
return nil, err
@@ -136,7 +133,6 @@ func NewProvider() (*provider, error) {
return nil, err
}
}
sessionCollection, err := arangodb.Collection(ctx, models.Collections.Session)
if err != nil {
return nil, err
@@ -144,7 +140,6 @@ func NewProvider() (*provider, error) {
sessionCollection.EnsureHashIndex(ctx, []string{"user_id"}, &arangoDriver.EnsureHashIndexOptions{
Sparse: true,
})
envCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Env)
if err != nil {
return nil, err
@@ -155,7 +150,6 @@ func NewProvider() (*provider, error) {
return nil, err
}
}
webhookCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.Webhook)
if err != nil {
return nil, err
@@ -166,7 +160,6 @@ func NewProvider() (*provider, error) {
return nil, err
}
}
webhookCollection, err := arangodb.Collection(ctx, models.Collections.Webhook)
if err != nil {
return nil, err
@@ -186,7 +179,6 @@ func NewProvider() (*provider, error) {
return nil, err
}
}
webhookLogCollection, err := arangodb.Collection(ctx, models.Collections.WebhookLog)
if err != nil {
return nil, err
@@ -194,7 +186,6 @@ func NewProvider() (*provider, error) {
webhookLogCollection.EnsureHashIndex(ctx, []string{"webhook_id"}, &arangoDriver.EnsureHashIndexOptions{
Sparse: true,
})
emailTemplateCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.EmailTemplate)
if err != nil {
return nil, err
@@ -205,7 +196,6 @@ func NewProvider() (*provider, error) {
return nil, err
}
}
emailTemplateCollection, err := arangodb.Collection(ctx, models.Collections.EmailTemplate)
if err != nil {
return nil, err
@@ -214,7 +204,6 @@ func NewProvider() (*provider, error) {
Unique: true,
Sparse: true,
})
otpCollectionExists, err := arangodb.CollectionExists(ctx, models.Collections.OTP)
if err != nil {
return nil, err
@@ -225,16 +214,14 @@ func NewProvider() (*provider, error) {
return nil, err
}
}
otpCollection, err := arangodb.Collection(ctx, models.Collections.OTP)
if err != nil {
return nil, err
}
otpCollection.EnsureHashIndex(ctx, []string{"email"}, &arangoDriver.EnsureHashIndexOptions{
otpCollection.EnsureHashIndex(ctx, []string{models.FieldNameEmail, models.FieldNamePhoneNumber}, &arangoDriver.EnsureHashIndexOptions{
Unique: true,
Sparse: true,
})
return &provider{
db: arangodb,
}, err

View File

@@ -9,12 +9,11 @@ import (
)
// AddSession to save session information in database
func (p *provider) AddSession(ctx context.Context, session models.Session) error {
func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
session.Key = session.ID
}
session.CreatedAt = time.Now().Unix()
session.UpdatedAt = time.Now().Unix()
sessionCollection, _ := p.db.Collection(ctx, models.Collections.Session)
@@ -24,3 +23,8 @@ func (p *provider) AddSession(ctx context.Context, session models.Session) error
}
return nil
}
// DeleteSession to delete session information from database
func (p *provider) DeleteSession(ctx context.Context, userId string) error {
return nil
}

View File

@@ -18,7 +18,7 @@ import (
)
// AddUser to save user information in database
func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
user.Key = user.ID
@@ -52,7 +52,7 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
}
// UpdateUser to update user information in database
func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
user.UpdatedAt = time.Now().Unix()
collection, _ := p.db.Collection(ctx, models.Collections.User)
@@ -67,13 +67,12 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use
}
// DeleteUser to delete user information from database
func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
collection, _ := p.db.Collection(ctx, models.Collections.User)
_, err := collection.RemoveDocument(ctx, user.Key)
if err != nil {
return err
}
query := fmt.Sprintf(`FOR d IN %s FILTER d.user_id == @user_id REMOVE { _key: d._key } IN %s`, models.Collections.Session, models.Collections.Session)
bindVars := map[string]interface{}{
"user_id": user.Key,
@@ -83,65 +82,55 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
return err
}
defer cursor.Close()
return nil
}
// ListUsers to get list of users from database
func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) {
func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
var users []*model.User
sctx := arangoDriver.WithQueryFullCount(ctx)
query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.User, pagination.Offset, pagination.Limit)
cursor, err := p.db.Query(sctx, query, nil)
if err != nil {
return nil, err
}
defer cursor.Close()
paginationClone := pagination
paginationClone.Total = cursor.Statistics().FullCount()
for {
var user models.User
var user *models.User
meta, err := cursor.ReadDocument(ctx, &user)
if arangoDriver.IsNoMoreDocuments(err) {
break
} else if err != nil {
return nil, err
}
if meta.Key != "" {
users = append(users, user.AsAPIUser())
}
}
return &model.Users{
Pagination: &paginationClone,
Pagination: paginationClone,
Users: users,
}, nil
}
// GetUserByEmail to get user information from database using email address
func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) {
var user models.User
func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
var user *models.User
query := fmt.Sprintf("FOR d in %s FILTER d.email == @email RETURN d", models.Collections.User)
bindVars := map[string]interface{}{
"email": email,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
return user, err
}
defer cursor.Close()
for {
if !cursor.HasMore() {
if user.Key == "" {
if user == nil {
return user, fmt.Errorf("user not found")
}
break
@@ -151,28 +140,24 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.Use
return user, err
}
}
return user, nil
}
// GetUserByID to get user information from database using user ID
func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) {
var user models.User
func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
var user *models.User
query := fmt.Sprintf("FOR d in %s FILTER d._id == @id LIMIT 1 RETURN d", models.Collections.User)
bindVars := map[string]interface{}{
"id": id,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
return user, err
}
defer cursor.Close()
for {
if !cursor.HasMore() {
if user.Key == "" {
if user == nil {
return user, fmt.Errorf("user not found")
}
break
@@ -182,7 +167,6 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err
return user, err
}
}
return user, nil
}
@@ -191,12 +175,10 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err
func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error {
// set updated_at time for all users
data["updated_at"] = time.Now().Unix()
userInfoBytes, err := json.Marshal(data)
if err != nil {
return err
}
query := ""
if len(ids) > 0 {
keysArray := ""
@@ -209,33 +191,28 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
} else {
query = fmt.Sprintf("FOR u IN %s UPDATE u._key with %s IN %s", models.Collections.User, string(userInfoBytes), models.Collections.User)
}
_, err = p.db.Query(ctx, query, nil)
if err != nil {
return err
}
return nil
}
// GetUserByPhoneNumber to get user information from database using phone number
func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
var user models.User
var user *models.User
query := fmt.Sprintf("FOR d in %s FILTER d.phone_number == @phone_number RETURN d", models.Collections.User)
bindVars := map[string]interface{}{
"phone_number": phoneNumber,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
return nil, err
}
defer cursor.Close()
for {
if !cursor.HasMore() {
if user.Key == "" {
if user == nil {
return nil, fmt.Errorf("user not found")
}
break
@@ -245,6 +222,5 @@ func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string)
return nil, err
}
}
return &user, nil
return user, nil
}

View File

@@ -12,12 +12,11 @@ import (
)
// AddVerification to save verification request in database
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) {
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
verificationRequest.Key = verificationRequest.ID
}
verificationRequest.CreatedAt = time.Now().Unix()
verificationRequest.UpdatedAt = time.Now().Unix()
verificationRequestRequestCollection, _ := p.db.Collection(ctx, models.Collections.VerificationRequest)
@@ -27,27 +26,24 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
}
verificationRequest.Key = meta.Key
verificationRequest.ID = meta.ID.String()
return verificationRequest, nil
}
// GetVerificationRequestByToken to get verification request from database using token
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) {
var verificationRequest models.VerificationRequest
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
var verificationRequest *models.VerificationRequest
query := fmt.Sprintf("FOR d in %s FILTER d.token == @token LIMIT 1 RETURN d", models.Collections.VerificationRequest)
bindVars := map[string]interface{}{
"token": token,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
return verificationRequest, err
}
defer cursor.Close()
for {
if !cursor.HasMore() {
if verificationRequest.Key == "" {
if verificationRequest == nil {
return verificationRequest, fmt.Errorf("verification request not found")
}
break
@@ -57,29 +53,25 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri
return verificationRequest, err
}
}
return verificationRequest, nil
}
// GetVerificationRequestByEmail to get verification request by email from database
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) {
var verificationRequest models.VerificationRequest
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) {
var verificationRequest *models.VerificationRequest
query := fmt.Sprintf("FOR d in %s FILTER d.email == @email FILTER d.identifier == @identifier LIMIT 1 RETURN d", models.Collections.VerificationRequest)
bindVars := map[string]interface{}{
"email": email,
"identifier": identifier,
}
cursor, err := p.db.Query(ctx, query, bindVars)
if err != nil {
return verificationRequest, err
}
defer cursor.Close()
for {
if !cursor.HasMore() {
if verificationRequest.Key == "" {
if verificationRequest == nil {
return verificationRequest, fmt.Errorf("verification request not found")
}
break
@@ -89,27 +81,23 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
return verificationRequest, err
}
}
return verificationRequest, nil
}
// ListVerificationRequests to get list of verification requests from database
func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) {
func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
var verificationRequests []*model.VerificationRequest
sctx := arangoDriver.WithQueryFullCount(ctx)
query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.VerificationRequest, pagination.Offset, pagination.Limit)
cursor, err := p.db.Query(sctx, query, nil)
if err != nil {
return nil, err
}
defer cursor.Close()
paginationClone := pagination
paginationClone.Total = cursor.Statistics().FullCount()
for {
var verificationRequest models.VerificationRequest
var verificationRequest *models.VerificationRequest
meta, err := cursor.ReadDocument(ctx, &verificationRequest)
if arangoDriver.IsNoMoreDocuments(err) {
@@ -123,15 +111,14 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode
}
}
return &model.VerificationRequests{
VerificationRequests: verificationRequests,
Pagination: &paginationClone,
Pagination: paginationClone,
}, nil
}
// DeleteVerificationRequest to delete verification request from database
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error {
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
collection, _ := p.db.Collection(ctx, models.Collections.VerificationRequest)
_, err := collection.RemoveDocument(ctx, verificationRequest.Key)
if err != nil {

View File

@@ -14,7 +14,7 @@ import (
)
// AddWebhook to add webhook
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
webhook.Key = webhook.ID
@@ -33,7 +33,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
}
// UpdateWebhook to update webhook
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
@@ -50,11 +50,9 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
}
// ListWebhooks to list webhook
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
webhooks := []*model.Webhook{}
query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.Webhook, pagination.Offset, pagination.Limit)
sctx := arangoDriver.WithQueryFullCount(ctx)
cursor, err := p.db.Query(sctx, query, nil)
if err != nil {
@@ -64,9 +62,8 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
paginationClone := pagination
paginationClone.Total = cursor.Statistics().FullCount()
for {
var webhook models.Webhook
var webhook *models.Webhook
meta, err := cursor.ReadDocument(ctx, &webhook)
if arangoDriver.IsNoMoreDocuments(err) {
break
} else if err != nil {
@@ -79,14 +76,14 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
}
return &model.Webhooks{
Pagination: &paginationClone,
Pagination: paginationClone,
Webhooks: webhooks,
}, nil
}
// GetWebhookByID to get webhook by id
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
var webhook models.Webhook
var webhook *models.Webhook
query := fmt.Sprintf("FOR d in %s FILTER d._key == @webhook_id RETURN d", models.Collections.Webhook)
bindVars := map[string]interface{}{
"webhook_id": webhookID,
@@ -98,7 +95,7 @@ func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model
defer cursor.Close()
for {
if !cursor.HasMore() {
if webhook.Key == "" {
if webhook == nil {
return nil, fmt.Errorf("webhook not found")
}
break
@@ -124,7 +121,7 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string)
defer cursor.Close()
webhooks := []*model.Webhook{}
for {
var webhook models.Webhook
var webhook *models.Webhook
if _, err := cursor.ReadDocument(ctx, &webhook); driver.IsNoMoreDocuments(err) {
// We're done
break

View File

@@ -12,12 +12,11 @@ import (
)
// AddWebhookLog to add webhook log
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) {
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
webhookLog.Key = webhookLog.ID
}
webhookLog.Key = webhookLog.ID
webhookLog.CreatedAt = time.Now().Unix()
webhookLog.UpdatedAt = time.Now().Unix()
@@ -30,46 +29,38 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL
}
// ListWebhookLogs to list webhook logs
func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) {
func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
webhookLogs := []*model.WebhookLog{}
bindVariables := map[string]interface{}{}
query := fmt.Sprintf("FOR d in %s SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.WebhookLog, pagination.Offset, pagination.Limit)
if webhookID != "" {
query = fmt.Sprintf("FOR d in %s FILTER d.webhook_id == @webhook_id SORT d.created_at DESC LIMIT %d, %d RETURN d", models.Collections.WebhookLog, pagination.Offset, pagination.Limit)
bindVariables = map[string]interface{}{
"webhook_id": webhookID,
}
}
sctx := arangoDriver.WithQueryFullCount(ctx)
cursor, err := p.db.Query(sctx, query, bindVariables)
if err != nil {
return nil, err
}
defer cursor.Close()
paginationClone := pagination
paginationClone.Total = cursor.Statistics().FullCount()
for {
var webhookLog models.WebhookLog
var webhookLog *models.WebhookLog
meta, err := cursor.ReadDocument(ctx, &webhookLog)
if arangoDriver.IsNoMoreDocuments(err) {
break
} else if err != nil {
return nil, err
}
if meta.Key != "" {
webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog())
}
}
return &model.WebhookLogs{
Pagination: &paginationClone,
Pagination: paginationClone,
WebhookLogs: webhookLogs,
}, nil
}

View File

@@ -15,33 +15,28 @@ import (
)
// AddEmailTemplate to add EmailTemplate
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
}
emailTemplate.Key = emailTemplate.ID
emailTemplate.CreatedAt = time.Now().Unix()
emailTemplate.UpdatedAt = time.Now().Unix()
existingEmailTemplate, _ := p.GetEmailTemplateByEventName(ctx, emailTemplate.EventName)
if existingEmailTemplate != nil {
return nil, fmt.Errorf("Email template with %s event_name already exists", emailTemplate.EventName)
}
insertQuery := fmt.Sprintf("INSERT INTO %s (id, event_name, subject, design, template, created_at, updated_at) VALUES ('%s', '%s', '%s','%s','%s', %d, %d)", KeySpace+"."+models.Collections.EmailTemplate, emailTemplate.ID, emailTemplate.EventName, emailTemplate.Subject, emailTemplate.Design, emailTemplate.Template, emailTemplate.CreatedAt, emailTemplate.UpdatedAt)
err := p.db.Query(insertQuery).Exec()
if err != nil {
return nil, err
}
return emailTemplate.AsAPIEmailTemplate(), nil
}
// UpdateEmailTemplate to update EmailTemplate
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
emailTemplate.UpdatedAt = time.Now().Unix()
bytes, err := json.Marshal(emailTemplate)
if err != nil {
return nil, err
@@ -54,22 +49,18 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models
if err != nil {
return nil, err
}
updateFields := ""
for key, value := range emailTemplateMap {
if key == "_id" {
continue
}
if key == "_key" {
continue
}
if value == nil {
updateFields += fmt.Sprintf("%s = null,", key)
continue
}
valueType := reflect.TypeOf(value)
if valueType.Name() == "string" {
updateFields += fmt.Sprintf("%s = '%s', ", key, value.(string))
@@ -90,7 +81,7 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models
}
// ListEmailTemplates to list EmailTemplate
func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) {
func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
emailTemplates := []*model.EmailTemplate{}
paginationClone := pagination
@@ -120,7 +111,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
}
return &model.EmailTemplates{
Pagination: &paginationClone,
Pagination: paginationClone,
EmailTemplates: emailTemplates,
}, nil
}

View File

@@ -11,11 +11,10 @@ import (
)
// AddEnv to save environment information in database
func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
}
env.CreatedAt = time.Now().Unix()
env.UpdatedAt = time.Now().Unix()
insertEnvQuery := fmt.Sprintf("INSERT INTO %s (id, env, hash, created_at, updated_at) VALUES ('%s', '%s', '%s', %d, %d)", KeySpace+"."+models.Collections.Env, env.ID, env.EnvData, env.Hash, env.CreatedAt, env.UpdatedAt)
@@ -28,9 +27,8 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro
}
// UpdateEnv to update environment information in database
func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
env.UpdatedAt = time.Now().Unix()
updateEnvQuery := fmt.Sprintf("UPDATE %s SET env = '%s', updated_at = %d WHERE id = '%s'", KeySpace+"."+models.Collections.Env, env.EnvData, env.UpdatedAt, env.ID)
err := p.db.Query(updateEnvQuery).Exec()
if err != nil {
@@ -40,14 +38,12 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e
}
// GetEnv to get environment information from database
func (p *provider) GetEnv(ctx context.Context) (models.Env, error) {
func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
var env models.Env
query := fmt.Sprintf("SELECT id, env, hash, created_at, updated_at FROM %s LIMIT 1", KeySpace+"."+models.Collections.Env)
err := p.db.Query(query).Consistency(gocql.One).Scan(&env.ID, &env.EnvData, &env.Hash, &env.CreatedAt, &env.UpdatedAt)
if err != nil {
return env, err
return nil, err
}
return env, nil
return &env, nil
}

View File

@@ -2,6 +2,7 @@ package cassandradb
import (
"context"
"errors"
"fmt"
"time"
@@ -12,7 +13,20 @@ import (
// UpsertOTP to add or update otp
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
otp, _ := p.GetOTPByEmail(ctx, otpParam.Email)
// check if email or phone number is present
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
uniqueField := models.FieldNameEmail
if otpParam.Email == "" && otpParam.PhoneNumber != "" {
uniqueField = models.FieldNamePhoneNumber
}
var otp *models.OTP
if uniqueField == models.FieldNameEmail {
otp, _ = p.GetOTPByEmail(ctx, otpParam.Email)
} else {
otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber)
}
shouldCreate := false
if otp == nil {
shouldCreate = true
@@ -20,6 +34,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
ID: uuid.NewString(),
Otp: otpParam.Otp,
Email: otpParam.Email,
PhoneNumber: otpParam.PhoneNumber,
ExpiresAt: otpParam.ExpiresAt,
CreatedAt: time.Now().Unix(),
UpdatedAt: time.Now().Unix(),
@@ -32,7 +47,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
otp.UpdatedAt = time.Now().Unix()
query := ""
if shouldCreate {
query = fmt.Sprintf(`INSERT INTO %s (id, email, otp, expires_at, created_at, updated_at) VALUES ('%s', '%s', '%s', %d, %d, %d)`, KeySpace+"."+models.Collections.OTP, otp.ID, otp.Email, otp.Otp, otp.ExpiresAt, otp.CreatedAt, otp.UpdatedAt)
query = fmt.Sprintf(`INSERT INTO %s (id, email, phone_number, otp, expires_at, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', %d, %d, %d)`, KeySpace+"."+models.Collections.OTP, otp.ID, otp.Email, otp.PhoneNumber, otp.Otp, otp.ExpiresAt, otp.CreatedAt, otp.UpdatedAt)
} else {
query = fmt.Sprintf(`UPDATE %s SET otp = '%s', expires_at = %d, updated_at = %d WHERE id = '%s'`, KeySpace+"."+models.Collections.OTP, otp.Otp, otp.ExpiresAt, otp.UpdatedAt, otp.ID)
}
@@ -48,8 +63,19 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
// GetOTPByEmail to get otp for a given email address
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
var otp models.OTP
query := fmt.Sprintf(`SELECT id, email, otp, expires_at, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.OTP, emailAddress)
err := p.db.Query(query).Consistency(gocql.One).Scan(&otp.ID, &otp.Email, &otp.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt)
query := fmt.Sprintf(`SELECT id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.OTP, emailAddress)
err := p.db.Query(query).Consistency(gocql.One).Scan(&otp.ID, &otp.Email, &otp.PhoneNumber, &otp.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt)
if err != nil {
return nil, err
}
return &otp, nil
}
// GetOTPByPhoneNumber to get otp for a given phone number
func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
var otp models.OTP
query := fmt.Sprintf(`SELECT id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.OTP, phoneNumber)
err := p.db.Query(query).Consistency(gocql.One).Scan(&otp.ID, &otp.Email, &otp.PhoneNumber, &otp.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt)
if err != nil {
return nil, err
}

View File

@@ -254,7 +254,26 @@ func NewProvider() (*provider, error) {
if err != nil {
return nil, err
}
// Add phone_number column to otp table
otpAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (phone_number text);`, KeySpace, models.Collections.OTP)
err = session.Query(otpAlterQuery).Exec()
if err != nil {
log.Debug("Failed to alter table as column exists: ", err)
// continue
}
// Add app_data column to users table
appDataAlterQuery := fmt.Sprintf(`ALTER TABLE %s.%s ADD (app_data text);`, KeySpace, models.Collections.User)
err = session.Query(appDataAlterQuery).Exec()
if err != nil {
log.Debug("Failed to alter user table as app_data column exists: ", err)
// continue
}
// Add phone number index
otpIndexQueryPhoneNumber := fmt.Sprintf("CREATE INDEX IF NOT EXISTS authorizer_otp_phone_number ON %s.%s (phone_number)", KeySpace, models.Collections.OTP)
err = session.Query(otpIndexQueryPhoneNumber).Exec()
if err != nil {
return nil, err
}
return &provider{
db: session,
}, err

View File

@@ -10,14 +10,12 @@ import (
)
// AddSession to save session information in database
func (p *provider) AddSession(ctx context.Context, session models.Session) error {
func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
}
session.CreatedAt = time.Now().Unix()
session.UpdatedAt = time.Now().Unix()
insertSessionQuery := fmt.Sprintf("INSERT INTO %s (id, user_id, user_agent, ip, created_at, updated_at) VALUES ('%s', '%s', '%s', '%s', %d, %d)", KeySpace+"."+models.Collections.Session, session.ID, session.UserID, session.UserAgent, session.IP, session.CreatedAt, session.UpdatedAt)
err := p.db.Query(insertSessionQuery).Exec()
if err != nil {
@@ -25,3 +23,8 @@ func (p *provider) AddSession(ctx context.Context, session models.Session) error
}
return nil
}
// DeleteSession to delete session information from database
func (p *provider) DeleteSession(ctx context.Context, userId string) error {
return nil
}

View File

@@ -18,7 +18,7 @@ import (
)
// AddUser to save user information in database
func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
}
@@ -77,7 +77,6 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
values = values[:len(values)-1] + ")"
query := fmt.Sprintf("INSERT INTO %s %s VALUES %s IF NOT EXISTS", KeySpace+"."+models.Collections.User, fields, values)
err = p.db.Query(query).Exec()
if err != nil {
return user, err
@@ -87,7 +86,7 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
}
// UpdateUser to update user information in database
func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
user.UpdatedAt = time.Now().Unix()
bytes, err := json.Marshal(user)
@@ -138,13 +137,12 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use
}
// DeleteUser to delete user information from database
func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+models.Collections.User, user.ID)
err := p.db.Query(query).Exec()
if err != nil {
return err
}
getSessionsQuery := fmt.Sprintf("SELECT id FROM %s WHERE user_id = '%s' ALLOW FILTERING", KeySpace+"."+models.Collections.Session, user.ID)
scanner := p.db.Query(getSessionsQuery).Iter().Scanner()
sessionIDs := ""
@@ -167,7 +165,7 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
}
// ListUsers to get list of users from database
func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) {
func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
responseUsers := []*model.User{}
paginationClone := pagination
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.User)
@@ -179,14 +177,13 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (
// there is no offset in cassandra
// so we fetch till limit + offset
// and return the results from offset to limit
query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.User, pagination.Limit+pagination.Offset)
query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.User, pagination.Limit+pagination.Offset)
scanner := p.db.Query(query).Iter().Scanner()
counter := int64(0)
for scanner.Next() {
if counter >= pagination.Offset {
var user models.User
err := scanner.Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt)
err := scanner.Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.AppData, &user.CreatedAt, &user.UpdatedAt)
if err != nil {
return nil, err
}
@@ -195,31 +192,31 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (
counter++
}
return &model.Users{
Pagination: paginationClone,
Users: responseUsers,
Pagination: &paginationClone,
}, nil
}
// GetUserByEmail to get user information from database using email address
func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) {
func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
var user models.User
query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.User, email)
err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt)
query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s WHERE email = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.User, email)
err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.AppData, &user.CreatedAt, &user.UpdatedAt)
if err != nil {
return user, err
return nil, err
}
return user, nil
return &user, nil
}
// GetUserByID to get user information from database using user ID
func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) {
func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
var user models.User
query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1", KeySpace+"."+models.Collections.User, id)
err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt)
query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s WHERE id = '%s' LIMIT 1", KeySpace+"."+models.Collections.User, id)
err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.AppData, &user.CreatedAt, &user.UpdatedAt)
if err != nil {
return user, err
return nil, err
}
return user, nil
return &user, nil
}
// UpdateUsers to update multiple users, with parameters of user IDs slice
@@ -252,9 +249,8 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
}
updateFields = strings.Trim(updateFields, " ")
updateFields = strings.TrimSuffix(updateFields, ",")
query := ""
if ids != nil && len(ids) > 0 {
if len(ids) > 0 {
idsString := ""
for _, id := range ids {
idsString += fmt.Sprintf("'%s', ", id)
@@ -310,8 +306,8 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
// GetUserByPhoneNumber to get user information from database using phone number
func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
var user models.User
query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.User, phoneNumber)
err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.CreatedAt, &user.UpdatedAt)
query := fmt.Sprintf("SELECT id, email, email_verified_at, password, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, app_data, created_at, updated_at FROM %s WHERE phone_number = '%s' LIMIT 1 ALLOW FILTERING", KeySpace+"."+models.Collections.User, phoneNumber)
err := p.db.Query(query).Consistency(gocql.One).Scan(&user.ID, &user.Email, &user.EmailVerifiedAt, &user.Password, &user.SignupMethods, &user.GivenName, &user.FamilyName, &user.MiddleName, &user.Nickname, &user.Birthdate, &user.PhoneNumber, &user.PhoneNumberVerifiedAt, &user.Picture, &user.Roles, &user.RevokedTimestamp, &user.IsMultiFactorAuthEnabled, &user.AppData, &user.CreatedAt, &user.UpdatedAt)
if err != nil {
return nil, err
}

View File

@@ -12,7 +12,7 @@ import (
)
// AddVerification to save verification request in database
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) {
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
}
@@ -29,41 +29,39 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
}
// GetVerificationRequestByToken to get verification request from database using token
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) {
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
var verificationRequest models.VerificationRequest
query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s WHERE jwt_token = '%s' LIMIT 1`, KeySpace+"."+models.Collections.VerificationRequest, token)
err := p.db.Query(query).Consistency(gocql.One).Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt)
if err != nil {
return verificationRequest, err
return nil, err
}
return verificationRequest, nil
return &verificationRequest, nil
}
// GetVerificationRequestByEmail to get verification request by email from database
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) {
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) {
var verificationRequest models.VerificationRequest
query := fmt.Sprintf(`SELECT id, jwt_token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s WHERE email = '%s' AND identifier = '%s' LIMIT 1 ALLOW FILTERING`, KeySpace+"."+models.Collections.VerificationRequest, email, identifier)
err := p.db.Query(query).Consistency(gocql.One).Scan(&verificationRequest.ID, &verificationRequest.Token, &verificationRequest.Identifier, &verificationRequest.ExpiresAt, &verificationRequest.Email, &verificationRequest.Nonce, &verificationRequest.RedirectURI, &verificationRequest.CreatedAt, &verificationRequest.UpdatedAt)
if err != nil {
return verificationRequest, err
return nil, err
}
return verificationRequest, nil
return &verificationRequest, nil
}
// ListVerificationRequests to get list of verification requests from database
func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) {
func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
var verificationRequests []*model.VerificationRequest
paginationClone := pagination
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.VerificationRequest)
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
if err != nil {
return nil, err
}
// there is no offset in cassandra
// so we fetch till limit + offset
// and return the results from offset to limit
@@ -85,12 +83,12 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode
return &model.VerificationRequests{
VerificationRequests: verificationRequests,
Pagination: &paginationClone,
Pagination: paginationClone,
}, nil
}
// DeleteVerificationRequest to delete verification request from database
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error {
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+models.Collections.VerificationRequest, verificationRequest.ID)
err := p.db.Query(query).Exec()
if err != nil {

View File

@@ -15,7 +15,7 @@ import (
)
// AddWebhook to add webhook
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
}
@@ -33,7 +33,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
}
// UpdateWebhook to update webhook
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
@@ -81,7 +81,7 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
}
// ListWebhooks to list webhook
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
webhooks := []*model.Webhook{}
paginationClone := pagination
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.Webhook)
@@ -108,7 +108,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
}
return &model.Webhooks{
Pagination: &paginationClone,
Pagination: paginationClone,
Webhooks: webhooks,
}, nil
}

View File

@@ -12,7 +12,7 @@ import (
)
// AddWebhookLog to add webhook log
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) {
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
@@ -30,7 +30,7 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL
}
// ListWebhookLogs to list webhook logs
func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) {
func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
webhookLogs := []*model.WebhookLog{}
paginationClone := pagination
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.WebhookLog)
@@ -38,7 +38,6 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat
// so we fetch till limit + offset
// and return the results from offset to limit
query := fmt.Sprintf("SELECT id, http_status, response, request, webhook_id, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.WebhookLog, pagination.Limit+pagination.Offset)
if webhookID != "" {
totalCountQuery = fmt.Sprintf(`SELECT COUNT(*) FROM %s WHERE webhook_id='%s' ALLOW FILTERING`, KeySpace+"."+models.Collections.WebhookLog, webhookID)
query = fmt.Sprintf("SELECT id, http_status, response, request, webhook_id, created_at, updated_at FROM %s WHERE webhook_id = '%s' LIMIT %d ALLOW FILTERING", KeySpace+"."+models.Collections.WebhookLog, webhookID, pagination.Limit+pagination.Offset)
@@ -64,7 +63,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat
}
return &model.WebhookLogs{
Pagination: &paginationClone,
Pagination: paginationClone,
WebhookLogs: webhookLogs,
}, nil
}

View File

@@ -15,7 +15,7 @@ import (
)
// AddEmailTemplate to add EmailTemplate
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
@@ -37,7 +37,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em
}
// UpdateEmailTemplate to update EmailTemplate
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
bytes, err := json.Marshal(emailTemplate)
if err != nil {
return nil, err
@@ -67,7 +67,7 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models
}
// ListEmailTemplates to list EmailTemplate
func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) {
func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
emailTemplates := []*model.EmailTemplate{}
paginationClone := pagination
total, err := p.GetTotalDocs(ctx, models.Collections.EmailTemplate)
@@ -88,7 +88,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
}
for queryResult.Next() {
emailTemplate := models.EmailTemplate{}
var emailTemplate *models.EmailTemplate
err := queryResult.Row(&emailTemplate)
if err != nil {
log.Fatal(err)
@@ -102,54 +102,46 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
}
return &model.EmailTemplates{
Pagination: &paginationClone,
Pagination: paginationClone,
EmailTemplates: emailTemplates,
}, nil
}
// GetEmailTemplateByID to get EmailTemplate by id
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
emailTemplate := models.EmailTemplate{}
var emailTemplate *models.EmailTemplate
query := fmt.Sprintf(`SELECT _id, event_name, subject, design, template, created_at, updated_at FROM %s.%s WHERE _id = $1 LIMIT 1`, p.scopeName, models.Collections.EmailTemplate)
q, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
PositionalParameters: []interface{}{emailTemplateID},
})
if err != nil {
return nil, err
}
err = q.One(&emailTemplate)
if err != nil {
return nil, err
}
return emailTemplate.AsAPIEmailTemplate(), nil
}
// GetEmailTemplateByEventName to get EmailTemplate by event_name
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
emailTemplate := models.EmailTemplate{}
var emailTemplate models.EmailTemplate
query := fmt.Sprintf("SELECT _id, event_name, subject, design, template, created_at, updated_at FROM %s.%s WHERE event_name=$1 LIMIT 1", p.scopeName, models.Collections.EmailTemplate)
q, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
PositionalParameters: []interface{}{eventName},
})
if err != nil {
return nil, err
}
err = q.One(&emailTemplate)
if err != nil {
return nil, err
}
return emailTemplate.AsAPIEmailTemplate(), nil
}

View File

@@ -11,7 +11,7 @@ import (
)
// AddEnv to save environment information in database
func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
}
@@ -19,7 +19,6 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro
env.UpdatedAt = time.Now().Unix()
env.Key = env.ID
env.EncryptionKey = env.Hash
insertOpt := gocb.InsertOptions{
Context: ctx,
}
@@ -31,7 +30,7 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro
}
// UpdateEnv to update environment information in database
func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
env.UpdatedAt = time.Now().Unix()
env.EncryptionKey = env.Hash
@@ -40,17 +39,15 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e
Context: ctx,
PositionalParameters: []interface{}{env.EnvData, env.UpdatedAt, env.UpdatedAt, env.ID},
})
if err != nil {
return env, err
}
return env, nil
}
// GetEnv to get environment information from database
func (p *provider) GetEnv(ctx context.Context) (models.Env, error) {
var env models.Env
func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
var env *models.Env
query := fmt.Sprintf("SELECT _id, env, encryption_key, created_at, updated_at FROM %s.%s LIMIT 1", p.scopeName, models.Collections.Env)
q, err := p.db.Query(query, &gocb.QueryOptions{
@@ -61,7 +58,6 @@ func (p *provider) GetEnv(ctx context.Context) (models.Env, error) {
return env, err
}
err = q.One(&env)
if err != nil {
return env, err
}

View File

@@ -2,6 +2,7 @@ package couchbase
import (
"context"
"errors"
"fmt"
"time"
@@ -12,8 +13,20 @@ import (
// UpsertOTP to add or update otp
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
otp, _ := p.GetOTPByEmail(ctx, otpParam.Email)
// check if email or phone number is present
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
uniqueField := models.FieldNameEmail
if otpParam.Email == "" && otpParam.PhoneNumber != "" {
uniqueField = models.FieldNamePhoneNumber
}
var otp *models.OTP
if uniqueField == models.FieldNameEmail {
otp, _ = p.GetOTPByEmail(ctx, otpParam.Email)
} else {
otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber)
}
shouldCreate := false
if otp == nil {
shouldCreate = true
@@ -21,6 +34,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
ID: uuid.NewString(),
Otp: otpParam.Otp,
Email: otpParam.Email,
PhoneNumber: otpParam.PhoneNumber,
ExpiresAt: otpParam.ExpiresAt,
CreatedAt: time.Now().Unix(),
UpdatedAt: time.Now().Unix(),
@@ -29,7 +43,6 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
otp.Otp = otpParam.Otp
otp.ExpiresAt = otpParam.ExpiresAt
}
otp.UpdatedAt = time.Now().Unix()
if shouldCreate {
insertOpt := gocb.InsertOptions{
@@ -54,7 +67,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
// GetOTPByEmail to get otp for a given email address
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
otp := models.OTP{}
query := fmt.Sprintf(`SELECT _id, email, otp, expires_at, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1`, p.scopeName, models.Collections.OTP)
query := fmt.Sprintf(`SELECT _id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1`, p.scopeName, models.Collections.OTP)
q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
PositionalParameters: []interface{}{emailAddress},
@@ -63,11 +76,27 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
return nil, err
}
err = q.One(&otp)
if err != nil {
return nil, err
}
return &otp, nil
}
// GetOTPByPhoneNumber to get otp for a given phone number
func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
otp := models.OTP{}
query := fmt.Sprintf(`SELECT _id, email, phone_number, otp, expires_at, created_at, updated_at FROM %s.%s WHERE phone_number = $1 LIMIT 1`, p.scopeName, models.Collections.OTP)
q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
PositionalParameters: []interface{}{phoneNumber},
})
if err != nil {
return nil, err
}
err = q.One(&otp)
if err != nil {
return nil, err
}
return &otp, nil
}

View File

@@ -166,5 +166,9 @@ func GetIndex(scopeName string) map[string][]string {
otpIndex1 := fmt.Sprintf("CREATE INDEX OTPEmailIndex ON %s.%s(email)", scopeName, models.Collections.OTP)
indices[models.Collections.OTP] = []string{otpIndex1}
// OTP index
otpIndex2 := fmt.Sprintf("CREATE INDEX OTPPhoneNumberIndex ON %s.%s(phone_number)", scopeName, models.Collections.OTP)
indices[models.Collections.OTP] = []string{otpIndex2}
return indices
}

View File

@@ -10,11 +10,10 @@ import (
)
// AddSession to save session information in database
func (p *provider) AddSession(ctx context.Context, session models.Session) error {
func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
}
session.CreatedAt = time.Now().Unix()
session.UpdatedAt = time.Now().Unix()
insertOpt := gocb.InsertOptions{
@@ -24,7 +23,6 @@ func (p *provider) AddSession(ctx context.Context, session models.Session) error
if err != nil {
return err
}
return nil
}

View File

@@ -11,24 +11,19 @@ import (
func GetSetFields(webhookMap map[string]interface{}) (string, map[string]interface{}) {
params := make(map[string]interface{}, 1)
updateFields := ""
for key, value := range webhookMap {
if key == "_id" {
continue
}
if key == "_key" {
continue
}
if value == nil {
updateFields += fmt.Sprintf("%s=$%s,", key, key)
params[key] = "null"
continue
}
valueType := reflect.TypeOf(value)
if valueType.Name() == "string" {
updateFields += fmt.Sprintf("%s = $%s, ", key, key)
@@ -46,14 +41,11 @@ func GetSetFields(webhookMap map[string]interface{}) (string, map[string]interfa
func (p *provider) GetTotalDocs(ctx context.Context, collection string) (int64, error) {
totalDocs := TotalDocs{}
countQuery := fmt.Sprintf("SELECT COUNT(*) as Total FROM %s.%s", p.scopeName, collection)
queryRes, err := p.db.Query(countQuery, &gocb.QueryOptions{
Context: ctx,
})
queryRes.One(&totalDocs)
if err != nil {
return totalDocs.Total, err
}

View File

@@ -15,7 +15,7 @@ import (
)
// AddUser to save user information in database
func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
}
@@ -41,7 +41,7 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
}
// UpdateUser to update user information in database
func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
user.UpdatedAt = time.Now().Unix()
unsertOpt := gocb.UpsertOptions{
Context: ctx,
@@ -54,7 +54,7 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use
}
// DeleteUser to delete user information from database
func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
removeOpt := gocb.RemoveOptions{
Context: ctx,
}
@@ -66,12 +66,10 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
}
// ListUsers to get list of users from database
func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) {
func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
users := []*model.User{}
paginationClone := pagination
userQuery := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s.%s ORDER BY id OFFSET $1 LIMIT $2", p.scopeName, models.Collections.User)
queryResult, err := p.db.Query(userQuery, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
Context: ctx,
@@ -97,21 +95,20 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (
return nil, err
}
return &model.Users{
Pagination: &paginationClone,
Pagination: paginationClone,
Users: users,
}, nil
}
// GetUserByEmail to get user information from database using email address
func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) {
user := models.User{}
func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
var user *models.User
query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s.%s WHERE email = $1 LIMIT 1", p.scopeName, models.Collections.User)
q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
Context: ctx,
PositionalParameters: []interface{}{email},
})
if err != nil {
return user, err
}
@@ -119,13 +116,12 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.Use
if err != nil {
return user, err
}
return user, nil
}
// GetUserByID to get user information from database using user ID
func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) {
user := models.User{}
func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
var user *models.User
query := fmt.Sprintf("SELECT _id, email, email_verified_at, `password`, signup_methods, given_name, family_name, middle_name, nickname, birthdate, phone_number, phone_number_verified_at, picture, roles, revoked_timestamp, is_multi_factor_auth_enabled, created_at, updated_at FROM %s.%s WHERE _id = $1 LIMIT 1", p.scopeName, models.Collections.User)
q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
@@ -139,7 +135,6 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err
if err != nil {
return user, err
}
return user, nil
}
@@ -174,7 +169,6 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
return err
}
}
return nil
}
@@ -194,6 +188,5 @@ func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string)
if err != nil {
return user, err
}
return user, nil
}

View File

@@ -13,11 +13,10 @@ import (
)
// AddVerification to save verification request in database
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) {
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
}
verificationRequest.Key = verificationRequest.ID
verificationRequest.CreatedAt = time.Now().Unix()
verificationRequest.UpdatedAt = time.Now().Unix()
@@ -28,13 +27,12 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
if err != nil {
return verificationRequest, err
}
return verificationRequest, nil
}
// GetVerificationRequestByToken to get verification request from database using token
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) {
verificationRequest := models.VerificationRequest{}
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
var verificationRequest *models.VerificationRequest
params := make(map[string]interface{}, 1)
params["token"] = token
query := fmt.Sprintf("SELECT _id, token, identifier, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s.%s WHERE token=$1 LIMIT 1", p.scopeName, models.Collections.VerificationRequest)
@@ -57,7 +55,7 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri
}
// GetVerificationRequestByEmail to get verification request by email from database
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) {
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) {
query := fmt.Sprintf("SELECT _id, identifier, token, expires_at, email, nonce, redirect_uri, created_at, updated_at FROM %s.%s WHERE email=$1 AND identifier=$2 LIMIT 1", p.scopeName, models.Collections.VerificationRequest)
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
@@ -65,14 +63,11 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
PositionalParameters: []interface{}{email, identifier},
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
})
verificationRequest := models.VerificationRequest{}
if err != nil {
return verificationRequest, err
return nil, err
}
var verificationRequest *models.VerificationRequest
err = queryResult.One(&verificationRequest)
if err != nil {
return verificationRequest, err
}
@@ -80,7 +75,7 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
}
// ListVerificationRequests to get list of verification requests from database
func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) {
func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
var verificationRequests []*model.VerificationRequest
paginationClone := pagination
total, err := p.GetTotalDocs(ctx, models.Collections.VerificationRequest)
@@ -111,12 +106,12 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode
}
return &model.VerificationRequests{
VerificationRequests: verificationRequests,
Pagination: &paginationClone,
Pagination: paginationClone,
}, nil
}
// DeleteVerificationRequest to delete verification request from database
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error {
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
removeOpt := gocb.RemoveOptions{
Context: ctx,
}

View File

@@ -15,7 +15,7 @@ import (
)
// AddWebhook to add webhook
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
}
@@ -35,7 +35,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
}
// UpdateWebhook to update webhook
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
@@ -68,7 +68,7 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
}
// ListWebhooks to list webhook
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
webhooks := []*model.Webhook{}
paginationClone := pagination
params := make(map[string]interface{}, 1)
@@ -100,14 +100,14 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
return nil, err
}
return &model.Webhooks{
Pagination: &paginationClone,
Pagination: paginationClone,
Webhooks: webhooks,
}, nil
}
// GetWebhookByID to get webhook by id
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
var webhook models.Webhook
var webhook *models.Webhook
params := make(map[string]interface{}, 1)
params["_id"] = webhookID
query := fmt.Sprintf(`SELECT _id, event_description, event_name, endpoint, headers, enabled, created_at, updated_at FROM %s.%s WHERE _id=$_id LIMIT 1`, p.scopeName, models.Collections.Webhook)
@@ -141,7 +141,7 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string)
}
webhooks := []*model.Webhook{}
for queryResult.Next() {
var webhook models.Webhook
var webhook *models.Webhook
err := queryResult.Row(&webhook)
if err != nil {
log.Fatal(err)
@@ -162,11 +162,9 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er
Context: ctx,
}
_, err := p.db.Collection(models.Collections.Webhook).Remove(webhook.ID, &removeOpt)
if err != nil {
return err
}
query := fmt.Sprintf(`DELETE FROM %s.%s WHERE webhook_id=$webhook_id`, p.scopeName, models.Collections.WebhookLog)
_, err = p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
@@ -176,6 +174,5 @@ func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) er
if err != nil {
return err
}
return nil
}

View File

@@ -13,15 +13,13 @@ import (
)
// AddWebhookLog to add webhook log
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) {
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
webhookLog.Key = webhookLog.ID
webhookLog.CreatedAt = time.Now().Unix()
webhookLog.UpdatedAt = time.Now().Unix()
insertOpt := gocb.InsertOptions{
Context: ctx,
}
@@ -29,19 +27,16 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL
if err != nil {
return webhookLog.AsAPIWebhookLog(), err
}
return webhookLog.AsAPIWebhookLog(), nil
}
// ListWebhookLogs to list webhook logs
func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) {
func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
var query string
var err error
webhookLogs := []*model.WebhookLog{}
params := make(map[string]interface{}, 1)
paginationClone := pagination
params["webhookID"] = webhookID
params["offset"] = paginationClone.Offset
params["limit"] = paginationClone.Limit
@@ -55,13 +50,11 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat
} else {
query = fmt.Sprintf("SELECT _id, http_status, response, request, webhook_id, created_at, updated_at FROM %s.%s OFFSET $offset LIMIT $limit", p.scopeName, models.Collections.WebhookLog)
}
queryResult, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
NamedParameters: params,
})
if err != nil {
return nil, err
}
@@ -73,13 +66,12 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat
}
webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog())
}
if err := queryResult.Err(); err != nil {
return nil, err
}
return &model.WebhookLogs{
Pagination: &paginationClone,
Pagination: paginationClone,
WebhookLogs: webhookLogs,
}, nil
}

View File

@@ -12,7 +12,7 @@ import (
)
// AddEmailTemplate to add EmailTemplate
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
collection := p.db.Table(models.Collections.EmailTemplate)
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
@@ -31,7 +31,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em
}
// UpdateEmailTemplate to update EmailTemplate
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
collection := p.db.Table(models.Collections.EmailTemplate)
emailTemplate.UpdatedAt = time.Now().Unix()
err := UpdateByHashKey(collection, "id", emailTemplate.ID, emailTemplate)
@@ -42,23 +42,19 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models
}
// ListEmailTemplates to list EmailTemplate
func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) {
var emailTemplate models.EmailTemplate
func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
var emailTemplate *models.EmailTemplate
var iter dynamo.PagingIter
var lastEval dynamo.PagingKey
var iteration int64 = 0
collection := p.db.Table(models.Collections.EmailTemplate)
emailTemplates := []*model.EmailTemplate{}
paginationClone := pagination
scanner := collection.Scan()
count, err := scanner.Count()
if err != nil {
return nil, err
}
for (paginationClone.Offset + paginationClone.Limit) > iteration {
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
for iter.NextWithContext(ctx, &emailTemplate) {
@@ -69,11 +65,9 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
lastEval = iter.LastEvaluatedKey()
iteration += paginationClone.Limit
}
paginationClone.Total = count
return &model.EmailTemplates{
Pagination: &paginationClone,
Pagination: paginationClone,
EmailTemplates: emailTemplates,
}, nil
}
@@ -81,7 +75,7 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
// GetEmailTemplateByID to get EmailTemplate by id
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
collection := p.db.Table(models.Collections.EmailTemplate)
var emailTemplate models.EmailTemplate
var emailTemplate *models.EmailTemplate
err := collection.Get("id", emailTemplateID).OneWithContext(ctx, &emailTemplate)
if err != nil {
return nil, err
@@ -92,9 +86,8 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str
// GetEmailTemplateByEventName to get EmailTemplate by event_name
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
collection := p.db.Table(models.Collections.EmailTemplate)
var emailTemplates []models.EmailTemplate
var emailTemplate models.EmailTemplate
var emailTemplates []*models.EmailTemplate
var emailTemplate *models.EmailTemplate
err := collection.Scan().Index("event_name").Filter("'event_name' = ?", eventName).Limit(1).AllWithContext(ctx, &emailTemplates)
if err != nil {
return nil, err
@@ -112,7 +105,6 @@ func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName st
func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model.EmailTemplate) error {
collection := p.db.Table(models.Collections.EmailTemplate)
err := collection.Delete("id", emailTemplate.ID).RunWithContext(ctx)
if err != nil {
return err
}

View File

@@ -11,34 +11,26 @@ import (
)
// AddEnv to save environment information in database
func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
collection := p.db.Table(models.Collections.Env)
if env.ID == "" {
env.ID = uuid.New().String()
}
env.Key = env.ID
env.CreatedAt = time.Now().Unix()
env.UpdatedAt = time.Now().Unix()
err := collection.Put(env).RunWithContext(ctx)
if err != nil {
return env, err
}
return env, nil
}
// UpdateEnv to update environment information in database
func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
collection := p.db.Table(models.Collections.Env)
env.UpdatedAt = time.Now().Unix()
err := UpdateByHashKey(collection, "id", env.ID, env)
if err != nil {
return env, err
}
@@ -46,26 +38,21 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e
}
// GetEnv to get environment information from database
func (p *provider) GetEnv(ctx context.Context) (models.Env, error) {
var env models.Env
func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
var env *models.Env
collection := p.db.Table(models.Collections.Env)
// As there is no Findone supported.
iter := collection.Scan().Limit(1).Iter()
for iter.NextWithContext(ctx, &env) {
if env.ID == "" {
if env == nil {
return env, errors.New("no documets found")
} else {
return env, nil
}
}
err := iter.Err()
if err != nil {
return env, fmt.Errorf("config not found")
}
return env, nil
}

View File

@@ -11,7 +11,20 @@ import (
// UpsertOTP to add or update otp
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
otp, _ := p.GetOTPByEmail(ctx, otpParam.Email)
// check if email or phone number is present
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
uniqueField := models.FieldNameEmail
if otpParam.Email == "" && otpParam.PhoneNumber != "" {
uniqueField = models.FieldNamePhoneNumber
}
var otp *models.OTP
if uniqueField == models.FieldNameEmail {
otp, _ = p.GetOTPByEmail(ctx, otpParam.Email)
} else {
otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber)
}
shouldCreate := false
if otp == nil {
id := uuid.NewString()
@@ -20,6 +33,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
Key: id,
Otp: otpParam.Otp,
Email: otpParam.Email,
PhoneNumber: otpParam.PhoneNumber,
ExpiresAt: otpParam.ExpiresAt,
CreatedAt: time.Now().Unix(),
}
@@ -28,10 +42,8 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
otp.Otp = otpParam.Otp
otp.ExpiresAt = otpParam.ExpiresAt
}
collection := p.db.Table(models.Collections.OTP)
otp.UpdatedAt = time.Now().Unix()
var err error
if shouldCreate {
err = collection.Put(otp).RunWithContext(ctx)
@@ -41,7 +53,6 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
if err != nil {
return nil, err
}
return otp, nil
}
@@ -49,32 +60,42 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
var otps []models.OTP
var otp models.OTP
collection := p.db.Table(models.Collections.OTP)
err := collection.Scan().Index("email").Filter("'email' = ?", emailAddress).Limit(1).AllWithContext(ctx, &otps)
if err != nil {
return nil, err
}
if len(otps) > 0 {
otp = otps[0]
return &otp, nil
} else {
return nil, errors.New("no docuemnt found")
}
return nil, errors.New("no docuemnt found")
}
// GetOTPByPhoneNumber to get otp for a given phone number
func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
var otps []models.OTP
var otp models.OTP
collection := p.db.Table(models.Collections.OTP)
err := collection.Scan().Filter("'phone_number' = ?", phoneNumber).Limit(1).AllWithContext(ctx, &otps)
if err != nil {
return nil, err
}
if len(otps) > 0 {
otp = otps[0]
return &otp, nil
}
return nil, errors.New("no docuemnt found")
}
// DeleteOTP to delete otp
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
collection := p.db.Table(models.Collections.OTP)
if otp.ID != "" {
err := collection.Delete("id", otp.ID).RunWithContext(ctx)
if err != nil {
return err
}
}
return nil
}

View File

@@ -31,21 +31,19 @@ func NewProvider() (*provider, error) {
if awsRegion != "" {
config.Region = aws.String(awsRegion)
}
// custom awsAccessKeyID, awsSecretAccessKey took first priority, if not then fetch config from aws credentials
if awsAccessKeyID != "" && awsSecretAccessKey != "" {
config.Credentials = credentials.NewStaticCredentials(awsAccessKeyID, awsSecretAccessKey, "")
} else if dbURL != "" {
log.Debug("Tring to use database url for dynamodb")
// static config in case of testing or local-setup
config.Credentials = credentials.NewStaticCredentials("key", "key", "")
config.Endpoint = aws.String(dbURL)
} else {
log.Debugf("%s or %s or %s not found. Trying to load default credentials from aws config", constants.EnvAwsRegion, constants.EnvAwsAccessKeyID, constants.EnvAwsSecretAccessKey)
}
session := session.Must(session.NewSession(&config))
db := dynamo.New(session)
db.CreateTable(models.Collections.User, models.User{}).Wait()
db.CreateTable(models.Collections.Session, models.Session{}).Wait()
db.CreateTable(models.Collections.EmailTemplate, models.EmailTemplate{}).Wait()
@@ -54,7 +52,6 @@ func NewProvider() (*provider, error) {
db.CreateTable(models.Collections.VerificationRequest, models.VerificationRequest{}).Wait()
db.CreateTable(models.Collections.Webhook, models.Webhook{}).Wait()
db.CreateTable(models.Collections.WebhookLog, models.WebhookLog{}).Wait()
return &provider{
db: db,
}, nil

View File

@@ -9,13 +9,11 @@ import (
)
// AddSession to save session information in database
func (p *provider) AddSession(ctx context.Context, session models.Session) error {
func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
collection := p.db.Table(models.Collections.Session)
if session.ID == "" {
session.ID = uuid.New().String()
}
session.CreatedAt = time.Now().Unix()
session.UpdatedAt = time.Now().Unix()
err := collection.Put(session).RunWithContext(ctx)

View File

@@ -9,16 +9,13 @@ import (
func UpdateByHashKey(table dynamo.Table, hashKey string, hashValue string, item interface{}) error {
existingValue, err := dynamo.MarshalItem(item)
var i interface{}
if err != nil {
return err
}
nullableValue, err := dynamodbattribute.MarshalMap(item)
if err != nil {
return err
}
u := table.Update(hashKey, hashValue)
for k, v := range existingValue {
if k == hashKey {
@@ -26,7 +23,6 @@ func UpdateByHashKey(table dynamo.Table, hashKey string, hashValue string, item
}
u = u.Set(k, v)
}
for k, v := range nullableValue {
if k == hashKey {
continue
@@ -36,11 +32,9 @@ func UpdateByHashKey(table dynamo.Table, hashKey string, hashValue string, item
u = u.SetNullable(k, v)
}
}
err = u.Run()
if err != nil {
return err
}
return nil
}

View File

@@ -18,13 +18,11 @@ import (
)
// AddUser to save user information in database
func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
collection := p.db.Table(models.Collections.User)
if user.ID == "" {
user.ID = uuid.New().String()
}
if user.Roles == "" {
defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
@@ -32,18 +30,14 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
}
user.Roles = defaultRoles
}
if user.PhoneNumber != nil && strings.TrimSpace(refs.StringValue(user.PhoneNumber)) != "" {
if u, _ := p.GetUserByPhoneNumber(ctx, refs.StringValue(user.PhoneNumber)); u != nil {
return user, fmt.Errorf("user with given phone number already exists")
}
}
user.CreatedAt = time.Now().Unix()
user.UpdatedAt = time.Now().Unix()
err := collection.Put(user).RunWithContext(ctx)
if err != nil {
return user, err
}
@@ -51,18 +45,14 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
}
// UpdateUser to update user information in database
func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
collection := p.db.Table(models.Collections.User)
if user.ID != "" {
user.UpdatedAt = time.Now().Unix()
err := UpdateByHashKey(collection, "id", user.ID, user)
if err != nil {
return user, err
}
if err != nil {
return user, err
}
@@ -72,18 +62,15 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use
}
// DeleteUser to delete user information from database
func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
collection := p.db.Table(models.Collections.User)
sessionCollection := p.db.Table(models.Collections.Session)
if user.ID != "" {
err := collection.Delete("id", user.ID).Run()
if err != nil {
return err
}
_, err = sessionCollection.Batch("id").Write().Delete(dynamo.Keys{"user_id", user.ID}).RunWithContext(ctx)
if err != nil {
return err
}
@@ -92,23 +79,19 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
}
// ListUsers to get list of users from database
func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) {
var user models.User
func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
var user *models.User
var lastEval dynamo.PagingKey
var iter dynamo.PagingIter
var iteration int64 = 0
collection := p.db.Table(models.Collections.User)
users := []*model.User{}
paginationClone := pagination
scanner := collection.Scan()
count, err := scanner.Count()
if err != nil {
return nil, err
}
for (paginationClone.Offset + paginationClone.Limit) > iteration {
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
for iter.NextWithContext(ctx, &user) {
@@ -119,48 +102,39 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (
lastEval = iter.LastEvaluatedKey()
iteration += paginationClone.Limit
}
err = iter.Err()
if err != nil {
return nil, err
}
paginationClone.Total = count
return &model.Users{
Pagination: &paginationClone,
Pagination: paginationClone,
Users: users,
}, nil
}
// GetUserByEmail to get user information from database using email address
func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) {
var users []models.User
var user models.User
func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
var users []*models.User
var user *models.User
collection := p.db.Table(models.Collections.User)
err := collection.Scan().Index("email").Filter("'email' = ?", email).AllWithContext(ctx, &users)
if err != nil {
return user, nil
}
if len(users) > 0 {
user = users[0]
return user, nil
} else {
return user, errors.New("no record found")
}
}
// GetUserByID to get user information from database using user ID
func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) {
func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
collection := p.db.Table(models.Collections.User)
var user models.User
var user *models.User
err := collection.Get("id", id).OneWithContext(ctx, &user)
if err != nil {
if user.Email == "" {
return user, errors.New("no documets found")
@@ -186,7 +160,6 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
} else {
// as there is no facility to update all doc - https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SQLtoNoSQL.UpdateData.html
userCollection.Scan().All(&allUsers)
for _, user := range allUsers {
err = UpdateByHashKey(userCollection, "id", user.ID, data)
if err == nil {
@@ -194,7 +167,6 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
}
}
}
if err != nil {
return err
} else {
@@ -205,19 +177,16 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
// GetUserByPhoneNumber to get user information from database using phone number
func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
var users []models.User
var user models.User
var users []*models.User
var user *models.User
collection := p.db.Table(models.Collections.User)
err := collection.Scan().Filter("'phone_number' = ?", phoneNumber).AllWithContext(ctx, &users)
if err != nil {
return nil, err
}
if len(users) > 0 {
user = users[0]
return &user, nil
return user, nil
} else {
return nil, errors.New("no record found")
}

View File

@@ -11,9 +11,8 @@ import (
)
// AddVerification to save verification request in database
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) {
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
collection := p.db.Table(models.Collections.VerificationRequest)
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
verificationRequest.CreatedAt = time.Now().Unix()
@@ -23,20 +22,17 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
return verificationRequest, err
}
}
return verificationRequest, nil
}
// GetVerificationRequestByToken to get verification request from database using token
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) {
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
collection := p.db.Table(models.Collections.VerificationRequest)
var verificationRequest models.VerificationRequest
var verificationRequest *models.VerificationRequest
iter := collection.Scan().Filter("'token' = ?", token).Iter()
for iter.NextWithContext(ctx, &verificationRequest) {
return verificationRequest, nil
}
err := iter.Err()
if err != nil {
return verificationRequest, err
@@ -45,14 +41,13 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri
}
// GetVerificationRequestByEmail to get verification request by email from database
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) {
var verificationRequest models.VerificationRequest
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) {
var verificationRequest *models.VerificationRequest
collection := p.db.Table(models.Collections.VerificationRequest)
iter := collection.Scan().Filter("'email' = ?", email).Filter("'identifier' = ?", identifier).Iter()
for iter.NextWithContext(ctx, &verificationRequest) {
return verificationRequest, nil
}
err := iter.Err()
if err != nil {
return verificationRequest, err
@@ -61,23 +56,19 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
}
// ListVerificationRequests to get list of verification requests from database
func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) {
func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
verificationRequests := []*model.VerificationRequest{}
var verificationRequest models.VerificationRequest
var verificationRequest *models.VerificationRequest
var lastEval dynamo.PagingKey
var iter dynamo.PagingIter
var iteration int64 = 0
collection := p.db.Table(models.Collections.VerificationRequest)
paginationClone := pagination
scanner := collection.Scan()
count, err := scanner.Count()
if err != nil {
return nil, err
}
for (paginationClone.Offset + paginationClone.Limit) > iteration {
iter = scanner.StartFrom(lastEval).Limit(paginationClone.Limit).Iter()
for iter.NextWithContext(ctx, &verificationRequest) {
@@ -92,20 +83,17 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode
lastEval = iter.LastEvaluatedKey()
iteration += paginationClone.Limit
}
paginationClone.Total = count
return &model.VerificationRequests{
VerificationRequests: verificationRequests,
Pagination: &paginationClone,
Pagination: paginationClone,
}, nil
}
// DeleteVerificationRequest to delete verification request from database
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error {
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
collection := p.db.Table(models.Collections.VerificationRequest)
if verificationRequest.ID != "" {
if verificationRequest != nil {
err := collection.Delete("id", verificationRequest.ID).RunWithContext(ctx)
if err != nil {

View File

@@ -15,7 +15,7 @@ import (
)
// AddWebhook to add webhook
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
collection := p.db.Table(models.Collections.Webhook)
if webhook.ID == "" {
webhook.ID = uuid.New().String()
@@ -33,7 +33,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
}
// UpdateWebhook to update webhook
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
@@ -48,9 +48,9 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
}
// ListWebhooks to list webhook
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
webhooks := []*model.Webhook{}
var webhook models.Webhook
var webhook *models.Webhook
var lastEval dynamo.PagingKey
var iter dynamo.PagingIter
var iteration int64 = 0
@@ -77,7 +77,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
}
paginationClone.Total = count
return &model.Webhooks{
Pagination: &paginationClone,
Pagination: paginationClone,
Webhooks: webhooks,
}, nil
}
@@ -85,7 +85,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
// GetWebhookByID to get webhook by id
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
collection := p.db.Table(models.Collections.Webhook)
var webhook models.Webhook
var webhook *models.Webhook
err := collection.Get("id", webhookID).OneWithContext(ctx, &webhook)
if err != nil {
return nil, err
@@ -114,14 +114,14 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string)
// DeleteWebhook to delete webhook
func (p *provider) DeleteWebhook(ctx context.Context, webhook *model.Webhook) error {
// Also delete webhook logs for given webhook id
if webhook.ID != "" {
if webhook != nil {
webhookCollection := p.db.Table(models.Collections.Webhook)
pagination := model.Pagination{}
webhookLogCollection := p.db.Table(models.Collections.WebhookLog)
err := webhookCollection.Delete("id", webhook.ID).RunWithContext(ctx)
if err != nil {
return err
}
pagination := &model.Pagination{}
webhookLogs, errIs := p.ListWebhookLogs(ctx, pagination, webhook.ID)
for _, webhookLog := range webhookLogs.WebhookLogs {
err = webhookLogCollection.Delete("id", webhookLog.ID).RunWithContext(ctx)

View File

@@ -11,18 +11,15 @@ import (
)
// AddWebhookLog to add webhook log
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) {
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
collection := p.db.Table(models.Collections.WebhookLog)
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
webhookLog.Key = webhookLog.ID
webhookLog.CreatedAt = time.Now().Unix()
webhookLog.UpdatedAt = time.Now().Unix()
err := collection.Put(webhookLog).RunWithContext(ctx)
if err != nil {
return nil, err
}
@@ -30,9 +27,9 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL
}
// ListWebhookLogs to list webhook logs
func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) {
func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
webhookLogs := []*model.WebhookLog{}
var webhookLog models.WebhookLog
var webhookLog *models.WebhookLog
var lastEval dynamo.PagingKey
var iter dynamo.PagingIter
var iteration int64 = 0
@@ -42,7 +39,6 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat
collection := p.db.Table(models.Collections.WebhookLog)
paginationClone := pagination
scanner := collection.Scan()
if webhookID != "" {
iter = scanner.Index("webhook_id").Filter("'webhook_id' = ?", webhookID).Iter()
for iter.NextWithContext(ctx, &webhookLog) {
@@ -68,11 +64,10 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat
iteration += paginationClone.Limit
}
}
paginationClone.Total = count
// paginationClone.Cursor = iter.LastEvaluatedKey()
return &model.WebhookLogs{
Pagination: &paginationClone,
Pagination: paginationClone,
WebhookLogs: webhookLogs,
}, nil
}

View File

@@ -12,15 +12,13 @@ import (
)
// AddEmailTemplate to add EmailTemplate
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
}
emailTemplate.Key = emailTemplate.ID
emailTemplate.CreatedAt = time.Now().Unix()
emailTemplate.UpdatedAt = time.Now().Unix()
emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection())
_, err := emailTemplateCollection.InsertOne(ctx, emailTemplate)
if err != nil {
@@ -30,60 +28,52 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em
}
// UpdateEmailTemplate to update EmailTemplate
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
emailTemplate.UpdatedAt = time.Now().Unix()
emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection())
_, err := emailTemplateCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": emailTemplate.ID}}, bson.M{"$set": emailTemplate}, options.MergeUpdateOptions())
if err != nil {
return nil, err
}
return emailTemplate.AsAPIEmailTemplate(), nil
}
// ListEmailTemplates to list EmailTemplate
func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) {
func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
var emailTemplates []*model.EmailTemplate
opts := options.Find()
opts.SetLimit(pagination.Limit)
opts.SetSkip(pagination.Offset)
opts.SetSort(bson.M{"created_at": -1})
paginationClone := pagination
emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection())
count, err := emailTemplateCollection.CountDocuments(ctx, bson.M{}, options.Count())
if err != nil {
return nil, err
}
paginationClone.Total = count
cursor, err := emailTemplateCollection.Find(ctx, bson.M{}, opts)
if err != nil {
return nil, err
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var emailTemplate models.EmailTemplate
var emailTemplate *models.EmailTemplate
err := cursor.Decode(&emailTemplate)
if err != nil {
return nil, err
}
emailTemplates = append(emailTemplates, emailTemplate.AsAPIEmailTemplate())
}
return &model.EmailTemplates{
Pagination: &paginationClone,
Pagination: paginationClone,
EmailTemplates: emailTemplates,
}, nil
}
// GetEmailTemplateByID to get EmailTemplate by id
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate
var emailTemplate *models.EmailTemplate
emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection())
err := emailTemplateCollection.FindOne(ctx, bson.M{"_id": emailTemplateID}).Decode(&emailTemplate)
if err != nil {
@@ -94,7 +84,7 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str
// GetEmailTemplateByEventName to get EmailTemplate by event_name
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate
var emailTemplate *models.EmailTemplate
emailTemplateCollection := p.db.Collection(models.Collections.EmailTemplate, options.Collection())
err := emailTemplateCollection.FindOne(ctx, bson.M{"event_name": eventName}).Decode(&emailTemplate)
if err != nil {
@@ -110,6 +100,5 @@ func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model
if err != nil {
return err
}
return nil
}

View File

@@ -12,11 +12,10 @@ import (
)
// AddEnv to save environment information in database
func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
}
env.CreatedAt = time.Now().Unix()
env.UpdatedAt = time.Now().Unix()
env.Key = env.ID
@@ -29,7 +28,7 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro
}
// UpdateEnv to update environment information in database
func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
env.UpdatedAt = time.Now().Unix()
configCollection := p.db.Collection(models.Collections.Env, options.Collection())
_, err := configCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": env.ID}}, bson.M{"$set": env}, options.MergeUpdateOptions())
@@ -40,25 +39,22 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e
}
// GetEnv to get environment information from database
func (p *provider) GetEnv(ctx context.Context) (models.Env, error) {
var env models.Env
func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
var env *models.Env
configCollection := p.db.Collection(models.Collections.Env, options.Collection())
cursor, err := configCollection.Find(ctx, bson.M{}, options.Find())
if err != nil {
return env, err
}
defer cursor.Close(ctx)
for cursor.Next(nil) {
err := cursor.Decode(&env)
if err != nil {
return env, err
}
}
if env.ID == "" {
if env == nil {
return env, fmt.Errorf("config not found")
}
return env, nil
}

View File

@@ -2,6 +2,7 @@ package mongodb
import (
"context"
"errors"
"time"
"github.com/authorizerdev/authorizer/server/db/models"
@@ -12,7 +13,20 @@ import (
// UpsertOTP to add or update otp
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) {
otp, _ := p.GetOTPByEmail(ctx, otpParam.Email)
// check if email or phone number is present
if otpParam.Email == "" && otpParam.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
uniqueField := models.FieldNameEmail
if otpParam.Email == "" && otpParam.PhoneNumber != "" {
uniqueField = models.FieldNamePhoneNumber
}
var otp *models.OTP
if uniqueField == models.FieldNameEmail {
otp, _ = p.GetOTPByEmail(ctx, otpParam.Email)
} else {
otp, _ = p.GetOTPByPhoneNumber(ctx, otpParam.PhoneNumber)
}
shouldCreate := false
if otp == nil {
id := uuid.NewString()
@@ -21,6 +35,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
Key: id,
Otp: otpParam.Otp,
Email: otpParam.Email,
PhoneNumber: otpParam.PhoneNumber,
ExpiresAt: otpParam.ExpiresAt,
CreatedAt: time.Now().Unix(),
}
@@ -41,20 +56,28 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
if err != nil {
return nil, err
}
return otp, nil
}
// GetOTPByEmail to get otp for a given email address
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
var otp models.OTP
otpCollection := p.db.Collection(models.Collections.OTP, options.Collection())
err := otpCollection.FindOne(ctx, bson.M{"email": emailAddress}).Decode(&otp)
if err != nil {
return nil, err
}
return &otp, nil
}
// GetOTPByPhoneNumber to get otp for a given phone number
func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
var otp models.OTP
otpCollection := p.db.Collection(models.Collections.OTP, options.Collection())
err := otpCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&otp)
if err != nil {
return nil, err
}
return &otp, nil
}

View File

@@ -118,6 +118,12 @@ func NewProvider() (*provider, error) {
Options: options.Index().SetUnique(true).SetSparse(true),
},
}, options.CreateIndexes())
otpCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{
Keys: bson.M{"phone_number": 1},
Options: options.Index().SetUnique(true).SetSparse(true),
},
}, options.CreateIndexes())
return &provider{
db: mongodb,

View File

@@ -10,7 +10,7 @@ import (
)
// AddSession to save session information in database
func (p *provider) AddSession(ctx context.Context, session models.Session) error {
func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
}
@@ -25,3 +25,8 @@ func (p *provider) AddSession(ctx context.Context, session models.Session) error
}
return nil
}
// DeleteSession to delete session information from database
func (p *provider) DeleteSession(ctx context.Context, userId string) error {
return nil
}

View File

@@ -16,11 +16,10 @@ import (
)
// AddUser to save user information in database
func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
}
if user.Roles == "" {
defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
@@ -36,12 +35,11 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
if err != nil {
return user, err
}
return user, nil
}
// UpdateUser to update user information in database
func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
user.UpdatedAt = time.Now().Unix()
userCollection := p.db.Collection(models.Collections.User, options.Collection())
_, err := userCollection.UpdateOne(ctx, bson.M{"_id": bson.M{"$eq": user.ID}}, bson.M{"$set": user}, options.MergeUpdateOptions())
@@ -52,83 +50,72 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use
}
// DeleteUser to delete user information from database
func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
userCollection := p.db.Collection(models.Collections.User, options.Collection())
_, err := userCollection.DeleteOne(ctx, bson.M{"_id": user.ID}, options.Delete())
if err != nil {
return err
}
sessionCollection := p.db.Collection(models.Collections.Session, options.Collection())
_, err = sessionCollection.DeleteMany(ctx, bson.M{"user_id": user.ID}, options.Delete())
if err != nil {
return err
}
return nil
}
// ListUsers to get list of users from database
func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) {
func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
var users []*model.User
opts := options.Find()
opts.SetLimit(pagination.Limit)
opts.SetSkip(pagination.Offset)
opts.SetSort(bson.M{"created_at": -1})
paginationClone := pagination
userCollection := p.db.Collection(models.Collections.User, options.Collection())
count, err := userCollection.CountDocuments(ctx, bson.M{}, options.Count())
if err != nil {
return nil, err
}
paginationClone.Total = count
cursor, err := userCollection.Find(ctx, bson.M{}, opts)
if err != nil {
return nil, err
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var user models.User
var user *models.User
err := cursor.Decode(&user)
if err != nil {
return nil, err
}
users = append(users, user.AsAPIUser())
}
return &model.Users{
Pagination: &paginationClone,
Pagination: paginationClone,
Users: users,
}, nil
}
// GetUserByEmail to get user information from database using email address
func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) {
var user models.User
func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
var user *models.User
userCollection := p.db.Collection(models.Collections.User, options.Collection())
err := userCollection.FindOne(ctx, bson.M{"email": email}).Decode(&user)
if err != nil {
return user, err
}
return user, nil
}
// GetUserByID to get user information from database using user ID
func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) {
var user models.User
func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
var user *models.User
userCollection := p.db.Collection(models.Collections.User, options.Collection())
err := userCollection.FindOne(ctx, bson.M{"_id": id}).Decode(&user)
if err != nil {
return user, err
}
return user, nil
}
@@ -137,17 +124,14 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err
func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error {
// set updated_at time for all users
data["updated_at"] = time.Now().Unix()
userCollection := p.db.Collection(models.Collections.User, options.Collection())
var res *mongo.UpdateResult
var err error
if ids != nil && len(ids) > 0 {
if len(ids) > 0 {
res, err = userCollection.UpdateMany(ctx, bson.M{"_id": bson.M{"$in": ids}}, bson.M{"$set": data})
} else {
res, err = userCollection.UpdateMany(ctx, bson.M{}, bson.M{"$set": data})
}
if err != nil {
return err
} else {
@@ -158,13 +142,11 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
// GetUserByPhoneNumber to get user information from database using phone number
func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
var user models.User
var user *models.User
userCollection := p.db.Collection(models.Collections.User, options.Collection())
err := userCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&user)
if err != nil {
return nil, err
}
return &user, nil
return user, nil
}

View File

@@ -12,7 +12,7 @@ import (
)
// AddVerification to save verification request in database
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) {
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
@@ -30,8 +30,8 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
}
// GetVerificationRequestByToken to get verification request from database using token
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) {
var verificationRequest models.VerificationRequest
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
var verificationRequest *models.VerificationRequest
verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
err := verificationRequestCollection.FindOne(ctx, bson.M{"token": token}).Decode(&verificationRequest)
@@ -43,8 +43,8 @@ func (p *provider) GetVerificationRequestByToken(ctx context.Context, token stri
}
// GetVerificationRequestByEmail to get verification request by email from database
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) {
var verificationRequest models.VerificationRequest
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) {
var verificationRequest *models.VerificationRequest
verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
err := verificationRequestCollection.FindOne(ctx, bson.M{"email": email, "identifier": identifier}).Decode(&verificationRequest)
@@ -56,7 +56,7 @@ func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email stri
}
// ListVerificationRequests to get list of verification requests from database
func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) {
func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
var verificationRequests []*model.VerificationRequest
opts := options.Find()
@@ -77,7 +77,7 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var verificationRequest models.VerificationRequest
var verificationRequest *models.VerificationRequest
err := cursor.Decode(&verificationRequest)
if err != nil {
return nil, err
@@ -87,12 +87,12 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode
return &model.VerificationRequests{
VerificationRequests: verificationRequests,
Pagination: &paginationClone,
Pagination: paginationClone,
}, nil
}
// DeleteVerificationRequest to delete verification request from database
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error {
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
_, err := verificationRequestCollection.DeleteOne(ctx, bson.M{"_id": verificationRequest.ID}, options.Delete())
if err != nil {

View File

@@ -14,7 +14,7 @@ import (
)
// AddWebhook to add webhook
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
}
@@ -32,7 +32,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
}
// UpdateWebhook to update webhook
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
@@ -47,7 +47,7 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
}
// ListWebhooks to list webhook
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
webhooks := []*model.Webhook{}
opts := options.Find()
opts.SetLimit(pagination.Limit)
@@ -66,7 +66,7 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var webhook models.Webhook
var webhook *models.Webhook
err := cursor.Decode(&webhook)
if err != nil {
return nil, err
@@ -74,14 +74,14 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
webhooks = append(webhooks, webhook.AsAPIWebhook())
}
return &model.Webhooks{
Pagination: &paginationClone,
Pagination: paginationClone,
Webhooks: webhooks,
}, nil
}
// GetWebhookByID to get webhook by id
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
var webhook models.Webhook
var webhook *models.Webhook
webhookCollection := p.db.Collection(models.Collections.Webhook, options.Collection())
err := webhookCollection.FindOne(ctx, bson.M{"_id": webhookID}).Decode(&webhook)
if err != nil {
@@ -104,7 +104,7 @@ func (p *provider) GetWebhookByEventName(ctx context.Context, eventName string)
}
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var webhook models.Webhook
var webhook *models.Webhook
err := cursor.Decode(&webhook)
if err != nil {
return nil, err

View File

@@ -12,7 +12,7 @@ import (
)
// AddWebhookLog to add webhook log
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) {
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
@@ -30,7 +30,7 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL
}
// ListWebhookLogs to list webhook logs
func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) {
func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
webhookLogs := []*model.WebhookLog{}
opts := options.Find()
opts.SetLimit(pagination.Limit)
@@ -59,7 +59,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat
defer cursor.Close(ctx)
for cursor.Next(ctx) {
var webhookLog models.WebhookLog
var webhookLog *models.WebhookLog
err := cursor.Decode(&webhookLog)
if err != nil {
return nil, err
@@ -68,7 +68,7 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat
}
return &model.WebhookLogs{
Pagination: &paginationClone,
Pagination: paginationClone,
WebhookLogs: webhookLogs,
}, nil
}

View File

@@ -10,7 +10,7 @@ import (
)
// AddEmailTemplate to add EmailTemplate
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
}
@@ -22,13 +22,13 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em
}
// UpdateEmailTemplate to update EmailTemplate
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
emailTemplate.UpdatedAt = time.Now().Unix()
return emailTemplate.AsAPIEmailTemplate(), nil
}
// ListEmailTemplates to list EmailTemplate
func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) {
func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
return nil, nil
}

View File

@@ -9,7 +9,7 @@ import (
)
// AddEnv to save environment information in database
func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
}
@@ -20,14 +20,14 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro
}
// UpdateEnv to update environment information in database
func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
env.UpdatedAt = time.Now().Unix()
return env, nil
}
// GetEnv to get environment information from database
func (p *provider) GetEnv(ctx context.Context) (models.Env, error) {
var env models.Env
func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
var env *models.Env
return env, nil
}

View File

@@ -16,6 +16,11 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
return nil, nil
}
// GetOTPByPhoneNumber to get otp for a given phone number
func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
return nil, nil
}
// DeleteOTP to delete otp
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
return nil

View File

@@ -9,11 +9,10 @@ import (
)
// AddSession to save session information in database
func (p *provider) AddSession(ctx context.Context, session models.Session) error {
func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
}
session.CreatedAt = time.Now().Unix()
session.UpdatedAt = time.Now().Unix()
return nil

View File

@@ -12,11 +12,10 @@ import (
)
// AddUser to save user information in database
func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
}
if user.Roles == "" {
defaultRoles, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyDefaultRoles)
if err != nil {
@@ -24,40 +23,36 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
}
user.Roles = defaultRoles
}
user.CreatedAt = time.Now().Unix()
user.UpdatedAt = time.Now().Unix()
return user, nil
}
// UpdateUser to update user information in database
func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
user.UpdatedAt = time.Now().Unix()
return user, nil
}
// DeleteUser to delete user information from database
func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
return nil
}
// ListUsers to get list of users from database
func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) {
func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
return nil, nil
}
// GetUserByEmail to get user information from database using email address
func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) {
var user models.User
func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
var user *models.User
return user, nil
}
// GetUserByID to get user information from database using user ID
func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) {
var user models.User
func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
var user *models.User
return user, nil
}
@@ -66,13 +61,11 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err
func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error {
// set updated_at time for all users
data["updated_at"] = time.Now().Unix()
return nil
}
// GetUserByPhoneNumber to get user information from database using phone number
func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
var user *models.User
return user, nil
}

View File

@@ -10,7 +10,7 @@ import (
)
// AddVerification to save verification request in database
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) {
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
}
@@ -22,25 +22,25 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
}
// GetVerificationRequestByToken to get verification request from database using token
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) {
var verificationRequest models.VerificationRequest
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
var verificationRequest *models.VerificationRequest
return verificationRequest, nil
}
// GetVerificationRequestByEmail to get verification request by email from database
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) {
var verificationRequest models.VerificationRequest
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) {
var verificationRequest *models.VerificationRequest
return verificationRequest, nil
}
// ListVerificationRequests to get list of verification requests from database
func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) {
func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
return nil, nil
}
// DeleteVerificationRequest to delete verification request from database
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error {
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
return nil
}

View File

@@ -12,7 +12,7 @@ import (
)
// AddWebhook to add webhook
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
}
@@ -25,7 +25,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
}
// UpdateWebhook to update webhook
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
@@ -35,7 +35,7 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
}
// ListWebhooks to list webhook
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
return nil, nil
}

View File

@@ -10,7 +10,7 @@ import (
)
// AddWebhookLog to add webhook log
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) {
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
@@ -22,6 +22,6 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL
}
// ListWebhookLogs to list webhook logs
func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) {
func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
return nil, nil
}

View File

@@ -9,50 +9,52 @@ import (
type Provider interface {
// AddUser to save user information in database
AddUser(ctx context.Context, user models.User) (models.User, error)
AddUser(ctx context.Context, user *models.User) (*models.User, error)
// UpdateUser to update user information in database
UpdateUser(ctx context.Context, user models.User) (models.User, error)
UpdateUser(ctx context.Context, user *models.User) (*models.User, error)
// DeleteUser to delete user information from database
DeleteUser(ctx context.Context, user models.User) error
DeleteUser(ctx context.Context, user *models.User) error
// ListUsers to get list of users from database
ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error)
ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error)
// GetUserByEmail to get user information from database using email address
GetUserByEmail(ctx context.Context, email string) (models.User, error)
GetUserByEmail(ctx context.Context, email string) (*models.User, error)
// GetUserByPhoneNumber to get user information from database using phone number
GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error)
// GetUserByID to get user information from database using user ID
GetUserByID(ctx context.Context, id string) (models.User, error)
GetUserByID(ctx context.Context, id string) (*models.User, error)
// UpdateUsers to update multiple users, with parameters of user IDs slice
// If ids set to nil / empty all the users will be updated
UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error
// AddVerification to save verification request in database
AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error)
AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error)
// GetVerificationRequestByToken to get verification request from database using token
GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error)
GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error)
// GetVerificationRequestByEmail to get verification request by email from database
GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error)
GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error)
// ListVerificationRequests to get list of verification requests from database
ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error)
ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error)
// DeleteVerificationRequest to delete verification request from database
DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error
DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error
// AddSession to save session information in database
AddSession(ctx context.Context, session models.Session) error
AddSession(ctx context.Context, session *models.Session) error
// DeleteSession to delete session information from database
DeleteSession(ctx context.Context, userId string) error
// AddEnv to save environment information in database
AddEnv(ctx context.Context, env models.Env) (models.Env, error)
AddEnv(ctx context.Context, env *models.Env) (*models.Env, error)
// UpdateEnv to update environment information in database
UpdateEnv(ctx context.Context, env models.Env) (models.Env, error)
UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error)
// GetEnv to get environment information from database
GetEnv(ctx context.Context) (models.Env, error)
GetEnv(ctx context.Context) (*models.Env, error)
// AddWebhook to add webhook
AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error)
AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error)
// UpdateWebhook to update webhook
UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error)
UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error)
// ListWebhooks to list webhook
ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error)
ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error)
// GetWebhookByID to get webhook by id
GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error)
// GetWebhookByEventName to get webhook by event_name
@@ -61,16 +63,16 @@ type Provider interface {
DeleteWebhook(ctx context.Context, webhook *model.Webhook) error
// AddWebhookLog to add webhook log
AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error)
AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error)
// ListWebhookLogs to list webhook logs
ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error)
ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error)
// AddEmailTemplate to add EmailTemplate
AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error)
AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error)
// UpdateEmailTemplate to update EmailTemplate
UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error)
UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error)
// ListEmailTemplates to list EmailTemplate
ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error)
ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error)
// GetEmailTemplateByID to get EmailTemplate by id
GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error)
// GetEmailTemplateByEventName to get EmailTemplate by event_name
@@ -82,6 +84,8 @@ type Provider interface {
UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, error)
// GetOTPByEmail to get otp for a given email address
GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error)
// GetOTPByPhoneNumber to get otp for a given phone number
GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error)
// DeleteOTP to delete otp
DeleteOTP(ctx context.Context, otp *models.OTP) error
}

View File

@@ -10,7 +10,7 @@ import (
)
// AddEmailTemplate to add EmailTemplate
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String()
}
@@ -27,7 +27,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em
}
// UpdateEmailTemplate to update EmailTemplate
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models.EmailTemplate) (*model.EmailTemplate, error) {
func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate *models.EmailTemplate) (*model.EmailTemplate, error) {
emailTemplate.UpdatedAt = time.Now().Unix()
res := p.db.Save(&emailTemplate)
@@ -38,9 +38,8 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models
}
// ListEmailTemplates to list EmailTemplate
func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagination) (*model.EmailTemplates, error) {
var emailTemplates []models.EmailTemplate
func (p *provider) ListEmailTemplate(ctx context.Context, pagination *model.Pagination) (*model.EmailTemplates, error) {
var emailTemplates []*models.EmailTemplate
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&emailTemplates)
if result.Error != nil {
return nil, result.Error
@@ -60,14 +59,14 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
responseEmailTemplates = append(responseEmailTemplates, w.AsAPIEmailTemplate())
}
return &model.EmailTemplates{
Pagination: &paginationClone,
Pagination: paginationClone,
EmailTemplates: responseEmailTemplates,
}, nil
}
// GetEmailTemplateByID to get EmailTemplate by id
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate
var emailTemplate *models.EmailTemplate
result := p.db.Where("id = ?", emailTemplateID).First(&emailTemplate)
if result.Error != nil {
@@ -78,7 +77,7 @@ func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID str
// GetEmailTemplateByEventName to get EmailTemplate by event_name
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) {
var emailTemplate models.EmailTemplate
var emailTemplate *models.EmailTemplate
result := p.db.Where("event_name = ?", eventName).First(&emailTemplate)
if result.Error != nil {
@@ -95,6 +94,5 @@ func (p *provider) DeleteEmailTemplate(ctx context.Context, emailTemplate *model
if result.Error != nil {
return result.Error
}
return nil
}

View File

@@ -9,7 +9,7 @@ import (
)
// AddEnv to save environment information in database
func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) AddEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
if env.ID == "" {
env.ID = uuid.New().String()
}
@@ -26,10 +26,9 @@ func (p *provider) AddEnv(ctx context.Context, env models.Env) (models.Env, erro
}
// UpdateEnv to update environment information in database
func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, error) {
func (p *provider) UpdateEnv(ctx context.Context, env *models.Env) (*models.Env, error) {
env.UpdatedAt = time.Now().Unix()
result := p.db.Save(&env)
if result.Error != nil {
return env, result.Error
}
@@ -37,13 +36,11 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e
}
// GetEnv to get environment information from database
func (p *provider) GetEnv(ctx context.Context) (models.Env, error) {
var env models.Env
func (p *provider) GetEnv(ctx context.Context) (*models.Env, error) {
var env *models.Env
result := p.db.First(&env)
if result.Error != nil {
return env, result.Error
}
return env, nil
}

View File

@@ -2,6 +2,7 @@ package sql
import (
"context"
"errors"
"time"
"github.com/authorizerdev/authorizer/server/db/models"
@@ -14,13 +15,19 @@ func (p *provider) UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP,
if otp.ID == "" {
otp.ID = uuid.New().String()
}
// check if email or phone number is present
if otp.Email == "" && otp.PhoneNumber == "" {
return nil, errors.New("email or phone_number is required")
}
uniqueField := models.FieldNameEmail
if otp.Email == "" && otp.PhoneNumber != "" {
uniqueField = models.FieldNamePhoneNumber
}
otp.Key = otp.ID
otp.CreatedAt = time.Now().Unix()
otp.UpdatedAt = time.Now().Unix()
res := p.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "email"}},
Columns: []clause.Column{{Name: uniqueField}},
DoUpdates: clause.AssignmentColumns([]string{"otp", "expires_at", "updated_at"}),
}).Create(&otp)
if res.Error != nil {
@@ -33,7 +40,6 @@ func (p *provider) UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP,
// GetOTPByEmail to get otp for a given email address
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
var otp models.OTP
result := p.db.Where("email = ?", emailAddress).First(&otp)
if result.Error != nil {
return nil, result.Error
@@ -41,6 +47,16 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
return &otp, nil
}
// GetOTPByPhoneNumber to get otp for a given phone number
func (p *provider) GetOTPByPhoneNumber(ctx context.Context, phoneNumber string) (*models.OTP, error) {
var otp models.OTP
result := p.db.Where("phone_number = ?", phoneNumber).First(&otp)
if result.Error != nil {
return nil, result.Error
}
return &otp, nil
}
// DeleteOTP to delete otp
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
result := p.db.Delete(&models.OTP{

View File

@@ -77,7 +77,7 @@ func NewProvider() (*provider, error) {
logrus.Debug("Failed to drop phone number constraint:", err)
}
err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, models.WebhookLog{}, models.EmailTemplate{}, &models.OTP{})
err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, &models.WebhookLog{}, &models.EmailTemplate{}, &models.OTP{})
if err != nil {
return nil, err
}

View File

@@ -10,7 +10,7 @@ import (
)
// AddSession to save session information in database
func (p *provider) AddSession(ctx context.Context, session models.Session) error {
func (p *provider) AddSession(ctx context.Context, session *models.Session) error {
if session.ID == "" {
session.ID = uuid.New().String()
}
@@ -27,3 +27,8 @@ func (p *provider) AddSession(ctx context.Context, session models.Session) error
}
return nil
}
// DeleteSession to delete session information from database
func (p *provider) DeleteSession(ctx context.Context, userId string) error {
return nil
}

View File

@@ -17,7 +17,7 @@ import (
)
// AddUser to save user information in database
func (p *provider) AddUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) AddUser(ctx context.Context, user *models.User) (*models.User, error) {
if user.ID == "" {
user.ID = uuid.New().String()
}
@@ -53,7 +53,7 @@ func (p *provider) AddUser(ctx context.Context, user models.User) (models.User,
}
// UpdateUser to update user information in database
func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.User, error) {
func (p *provider) UpdateUser(ctx context.Context, user *models.User) (*models.User, error) {
user.UpdatedAt = time.Now().Unix()
result := p.db.Save(&user)
@@ -66,7 +66,7 @@ func (p *provider) UpdateUser(ctx context.Context, user models.User) (models.Use
}
// DeleteUser to delete user information from database
func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
func (p *provider) DeleteUser(ctx context.Context, user *models.User) error {
result := p.db.Where("user_id = ?", user.ID).Delete(&models.Session{})
if result.Error != nil {
return result.Error
@@ -81,7 +81,7 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
}
// ListUsers to get list of users from database
func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (*model.Users, error) {
func (p *provider) ListUsers(ctx context.Context, pagination *model.Pagination) (*model.Users, error) {
var users []models.User
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&users)
if result.Error != nil {
@@ -103,31 +103,28 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (
paginationClone.Total = total
return &model.Users{
Pagination: &paginationClone,
Pagination: paginationClone,
Users: responseUsers,
}, nil
}
// GetUserByEmail to get user information from database using email address
func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.User, error) {
var user models.User
func (p *provider) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
var user *models.User
result := p.db.Where("email = ?", email).First(&user)
if result.Error != nil {
return user, result.Error
}
return user, nil
}
// GetUserByID to get user information from database using user ID
func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, error) {
var user models.User
func (p *provider) GetUserByID(ctx context.Context, id string) (*models.User, error) {
var user *models.User
result := p.db.Where("id = ?", id).First(&user)
if result.Error != nil {
return user, result.Error
}
return user, nil
}
@@ -136,14 +133,12 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err
func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error {
// set updated_at time for all users
data["updated_at"] = time.Now().Unix()
var res *gorm.DB
if ids != nil && len(ids) > 0 {
if len(ids) > 0 {
res = p.db.Model(&models.User{}).Where("id in ?", ids).Updates(data)
} else {
res = p.db.Model(&models.User{}).Updates(data)
}
if res.Error != nil {
return res.Error
}
@@ -154,10 +149,8 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) {
var user *models.User
result := p.db.Where("phone_number = ?", phoneNumber).First(&user)
if result.Error != nil {
return nil, result.Error
}
return user, nil
}

View File

@@ -11,11 +11,10 @@ import (
)
// AddVerification to save verification request in database
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) (models.VerificationRequest, error) {
func (p *provider) AddVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) (*models.VerificationRequest, error) {
if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String()
}
verificationRequest.Key = verificationRequest.ID
verificationRequest.CreatedAt = time.Now().Unix()
verificationRequest.UpdatedAt = time.Now().Unix()
@@ -23,75 +22,61 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
Columns: []clause.Column{{Name: "email"}, {Name: "identifier"}},
DoUpdates: clause.AssignmentColumns([]string{"token", "expires_at", "nonce", "redirect_uri"}),
}).Create(&verificationRequest)
if result.Error != nil {
return verificationRequest, result.Error
}
return verificationRequest, nil
}
// GetVerificationRequestByToken to get verification request from database using token
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (models.VerificationRequest, error) {
var verificationRequest models.VerificationRequest
func (p *provider) GetVerificationRequestByToken(ctx context.Context, token string) (*models.VerificationRequest, error) {
var verificationRequest *models.VerificationRequest
result := p.db.Where("token = ?", token).First(&verificationRequest)
if result.Error != nil {
return verificationRequest, result.Error
}
return verificationRequest, nil
}
// GetVerificationRequestByEmail to get verification request by email from database
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (models.VerificationRequest, error) {
var verificationRequest models.VerificationRequest
func (p *provider) GetVerificationRequestByEmail(ctx context.Context, email string, identifier string) (*models.VerificationRequest, error) {
var verificationRequest *models.VerificationRequest
result := p.db.Where("email = ? AND identifier = ?", email, identifier).First(&verificationRequest)
if result.Error != nil {
return verificationRequest, result.Error
}
return verificationRequest, nil
}
// ListVerificationRequests to get list of verification requests from database
func (p *provider) ListVerificationRequests(ctx context.Context, pagination model.Pagination) (*model.VerificationRequests, error) {
func (p *provider) ListVerificationRequests(ctx context.Context, pagination *model.Pagination) (*model.VerificationRequests, error) {
var verificationRequests []models.VerificationRequest
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&verificationRequests)
if result.Error != nil {
return nil, result.Error
}
responseVerificationRequests := []*model.VerificationRequest{}
for _, v := range verificationRequests {
responseVerificationRequests = append(responseVerificationRequests, v.AsAPIVerificationRequest())
}
var total int64
totalRes := p.db.Model(&models.VerificationRequest{}).Count(&total)
if totalRes.Error != nil {
return nil, totalRes.Error
}
paginationClone := pagination
paginationClone.Total = total
return &model.VerificationRequests{
VerificationRequests: responseVerificationRequests,
Pagination: &paginationClone,
Pagination: paginationClone,
}, nil
}
// DeleteVerificationRequest to delete verification request from database
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest models.VerificationRequest) error {
func (p *provider) DeleteVerificationRequest(ctx context.Context, verificationRequest *models.VerificationRequest) error {
result := p.db.Delete(&verificationRequest)
if result.Error != nil {
return result.Error
}
return nil
}

View File

@@ -12,7 +12,7 @@ import (
)
// AddWebhook to add webhook
func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) AddWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
if webhook.ID == "" {
webhook.ID = uuid.New().String()
}
@@ -29,7 +29,7 @@ func (p *provider) AddWebhook(ctx context.Context, webhook models.Webhook) (*mod
}
// UpdateWebhook to update webhook
func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*model.Webhook, error) {
func (p *provider) UpdateWebhook(ctx context.Context, webhook *models.Webhook) (*model.Webhook, error) {
webhook.UpdatedAt = time.Now().Unix()
// Event is changed
if !strings.Contains(webhook.EventName, "-") {
@@ -43,7 +43,7 @@ func (p *provider) UpdateWebhook(ctx context.Context, webhook models.Webhook) (*
}
// ListWebhooks to list webhook
func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination) (*model.Webhooks, error) {
func (p *provider) ListWebhook(ctx context.Context, pagination *model.Pagination) (*model.Webhooks, error) {
var webhooks []models.Webhook
result := p.db.Limit(int(pagination.Limit)).Offset(int(pagination.Offset)).Order("created_at DESC").Find(&webhooks)
if result.Error != nil {
@@ -61,14 +61,14 @@ func (p *provider) ListWebhook(ctx context.Context, pagination model.Pagination)
responseWebhooks = append(responseWebhooks, w.AsAPIWebhook())
}
return &model.Webhooks{
Pagination: &paginationClone,
Pagination: paginationClone,
Webhooks: responseWebhooks,
}, nil
}
// GetWebhookByID to get webhook by id
func (p *provider) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) {
var webhook models.Webhook
var webhook *models.Webhook
result := p.db.Where("id = ?", webhookID).First(&webhook)
if result.Error != nil {

View File

@@ -12,7 +12,7 @@ import (
)
// AddWebhookLog to add webhook log
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookLog) (*model.WebhookLog, error) {
func (p *provider) AddWebhookLog(ctx context.Context, webhookLog *models.WebhookLog) (*model.WebhookLog, error) {
if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String()
}
@@ -32,7 +32,7 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL
}
// ListWebhookLogs to list webhook logs
func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Pagination, webhookID string) (*model.WebhookLogs, error) {
func (p *provider) ListWebhookLogs(ctx context.Context, pagination *model.Pagination, webhookID string) (*model.WebhookLogs, error) {
var webhookLogs []models.WebhookLog
var result *gorm.DB
var totalRes *gorm.DB
@@ -63,6 +63,6 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat
}
return &model.WebhookLogs{
WebhookLogs: responseWebhookLogs,
Pagination: &paginationClone,
Pagination: paginationClone,
}, nil
}

View File

@@ -72,7 +72,6 @@ func getEmailTemplate(event string, data map[string]interface{}) (*model.EmailTe
return nil, err
}
subjectString := buf.String()
return &model.EmailTemplate{
Template: templateString,
Subject: subjectString,
@@ -92,7 +91,7 @@ func SendEmail(to []string, event string, data map[string]interface{}) error {
tmp, err := getEmailTemplate(event, data)
if err != nil {
log.Errorf("Failed to get event template: ", err)
log.Error("Failed to get event template: ", err)
return err
}
@@ -103,6 +102,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 +144,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)

89
server/env/env.go vendored
View File

@@ -19,7 +19,7 @@ import (
// InitEnv to initialize EnvData and through error if required env are not present
func InitAllEnv() error {
envData, err := GetEnvData()
if err != nil {
if err != nil || envData == nil {
log.Info("No env data found in db, using local clone of env data")
// get clone of current store
envData, err = memorystore.Provider.GetEnvStore()
@@ -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)
@@ -103,6 +104,15 @@ func InitAllEnv() error {
osDisableStrongPassword := os.Getenv(constants.EnvKeyDisableStrongPassword)
osEnforceMultiFactorAuthentication := os.Getenv(constants.EnvKeyEnforceMultiFactorAuthentication)
osDisableMultiFactorAuthentication := os.Getenv(constants.EnvKeyDisableMultiFactorAuthentication)
// phone verification var
osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification)
osDisablePlayground := os.Getenv(constants.EnvKeyDisablePlayGround)
// twilio vars
osTwilioApiKey := os.Getenv(constants.EnvKeyTwilioAPIKey)
osTwilioApiSecret := os.Getenv(constants.EnvKeyTwilioAPISecret)
osTwilioAccountSid := os.Getenv(constants.EnvKeyTwilioAccountSID)
osTwilioSender := os.Getenv(constants.EnvKeyTwilioSender)
// os slice vars
osAllowedOrigins := os.Getenv(constants.EnvKeyAllowedOrigins)
@@ -135,6 +145,7 @@ func InitAllEnv() error {
if val, ok := envData[constants.EnvAwsRegion]; !ok || val == "" {
envData[constants.EnvAwsRegion] = osAwsRegion
}
if osAwsRegion != "" && envData[constants.EnvAwsRegion] != osAwsRegion {
envData[constants.EnvAwsRegion] = osAwsRegion
}
@@ -257,6 +268,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 == "" {
@@ -583,7 +601,7 @@ func InitAllEnv() error {
if err != nil {
return err
}
if boolValue != envData[constants.EnvKeyDisableMagicLinkLogin].(bool) {
if boolValue != envData[constants.EnvKeyDisableMagicLinkLogin] {
envData[constants.EnvKeyDisableMagicLinkLogin] = boolValue
}
}
@@ -673,11 +691,11 @@ func InitAllEnv() error {
envData[constants.EnvKeyIsEmailServiceEnabled] = false
}
if envData[constants.EnvKeySmtpHost] != "" || envData[constants.EnvKeySmtpUsername] != "" || envData[constants.EnvKeySmtpPassword] != "" || envData[constants.EnvKeySenderEmail] != "" && envData[constants.EnvKeySmtpPort] != "" {
if envData[constants.EnvKeySmtpHost] != "" && envData[constants.EnvKeySmtpUsername] != "" && envData[constants.EnvKeySmtpPassword] != "" && envData[constants.EnvKeySenderEmail] != "" && envData[constants.EnvKeySmtpPort] != "" {
envData[constants.EnvKeyIsEmailServiceEnabled] = true
}
if envData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && !envData[constants.EnvKeyIsEmailServiceEnabled].(bool) {
if envData[constants.EnvKeyEnforceMultiFactorAuthentication].(bool) && !envData[constants.EnvKeyIsEmailServiceEnabled].(bool) && !envData[constants.EnvKeyIsSMSServiceEnabled].(bool) {
return errors.New("to enable multi factor authentication, please enable email service")
}
@@ -759,6 +777,69 @@ func InitAllEnv() error {
envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode
}
if val, ok := envData[constants.EnvKeyTwilioAPISecret]; !ok || val == "" {
envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret
}
if osTwilioApiSecret != "" && envData[constants.EnvKeyTwilioAPISecret] != osTwilioApiSecret {
envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret
}
if val, ok := envData[constants.EnvKeyTwilioAPIKey]; !ok || val == "" {
envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey
}
if osTwilioApiKey != "" && envData[constants.EnvKeyTwilioAPIKey] != osTwilioApiKey {
envData[constants.EnvKeyTwilioAPIKey] = osTwilioApiKey
}
if val, ok := envData[constants.EnvKeyTwilioAccountSID]; !ok || val == "" {
envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid
}
if osTwilioAccountSid != "" && envData[constants.EnvKeyTwilioAccountSID] != osTwilioAccountSid {
envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid
}
if val, ok := envData[constants.EnvKeyTwilioSender]; !ok || val == "" {
envData[constants.EnvKeyTwilioSender] = osTwilioSender
}
if osTwilioSender != "" && envData[constants.EnvKeyTwilioSender] != osTwilioSender {
envData[constants.EnvKeyTwilioSender] = osTwilioSender
}
if _, ok := envData[constants.EnvKeyDisablePhoneVerification]; !ok {
envData[constants.EnvKeyDisablePhoneVerification] = osDisablePhoneVerification == "false"
}
if osDisablePhoneVerification != "" {
boolValue, err := strconv.ParseBool(osDisablePhoneVerification)
if err != nil {
return err
}
if boolValue != envData[constants.EnvKeyDisablePhoneVerification] {
envData[constants.EnvKeyDisablePhoneVerification] = boolValue
}
}
if envData[constants.EnvKeyTwilioAPIKey] == "" || envData[constants.EnvKeyTwilioAPISecret] == "" || envData[constants.EnvKeyTwilioAccountSID] == "" || envData[constants.EnvKeyTwilioSender] == "" {
envData[constants.EnvKeyDisablePhoneVerification] = true
envData[constants.EnvKeyIsSMSServiceEnabled] = false
}
if envData[constants.EnvKeyTwilioAPIKey] != "" && envData[constants.EnvKeyTwilioAPISecret] != "" && envData[constants.EnvKeyTwilioAccountSID] != "" && envData[constants.EnvKeyTwilioSender] != "" {
envData[constants.EnvKeyDisablePhoneVerification] = false
envData[constants.EnvKeyIsSMSServiceEnabled] = true
}
if _, ok := envData[constants.EnvKeyDisablePlayGround]; !ok {
envData[constants.EnvKeyDisablePlayGround] = osDisablePlayground == "true"
}
if osDisablePlayground != "" {
boolValue, err := strconv.ParseBool(osDisablePlayground)
if err != nil {
return err
}
if boolValue != envData[constants.EnvKeyDisablePlayGround].(bool) {
envData[constants.EnvKeyDisablePlayGround] = boolValue
}
}
err = memorystore.Provider.UpdateEnvStore(envData)
if err != nil {
log.Debug("Error while updating env store: ", err)

View File

@@ -62,7 +62,7 @@ func GetEnvData() (map[string]interface{}, error) {
ctx := context.Background()
env, err := db.Provider.GetEnv(ctx)
// config not found in db
if err != nil {
if err != nil || env == nil {
log.Debug("Error while getting env data from db: ", err)
return result, err
}
@@ -112,7 +112,7 @@ func PersistEnv() error {
ctx := context.Background()
env, err := db.Provider.GetEnv(ctx)
// config not found in db
if err != nil || env.EnvData == "" {
if err != nil || env == nil {
// AES encryption needs 32 bit key only, so we chop off last 4 characters from 36 bit uuid
hash := uuid.New().String()[:36-4]
err := memorystore.Provider.UpdateEnvVariable(constants.EnvKeyEncryptionKey, hash)
@@ -121,25 +121,21 @@ func PersistEnv() error {
return err
}
encodedHash := crypto.EncryptB64(hash)
res, err := memorystore.Provider.GetEnvStore()
if err != nil {
log.Debug("Error while getting env store: ", err)
return err
}
encryptedConfig, err := crypto.EncryptEnvData(res)
if err != nil {
log.Debug("Error while encrypting env data: ", err)
return err
}
env = models.Env{
env = &models.Env{
Hash: encodedHash,
EnvData: encryptedConfig,
}
env, err = db.Provider.AddEnv(ctx, env)
_, err = db.Provider.AddEnv(ctx, env)
if err != nil {
log.Debug("Error while persisting env data to db: ", err)
return err
@@ -200,7 +196,7 @@ func PersistEnv() error {
envValue := strings.TrimSpace(os.Getenv(key))
if envValue != "" {
switch key {
case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure:
case constants.EnvKeyIsProd, constants.EnvKeyDisableBasicAuthentication, constants.EnvKeyDisableMobileBasicAuthentication, constants.EnvKeyDisableEmailVerification, constants.EnvKeyDisableLoginPage, constants.EnvKeyDisableMagicLinkLogin, constants.EnvKeyDisableSignUp, constants.EnvKeyDisableRedisForEnv, constants.EnvKeyDisableStrongPassword, constants.EnvKeyIsEmailServiceEnabled, constants.EnvKeyIsSMSServiceEnabled, constants.EnvKeyEnforceMultiFactorAuthentication, constants.EnvKeyDisableMultiFactorAuthentication, constants.EnvKeyAdminCookieSecure, constants.EnvKeyAppCookieSecure, constants.EnvKeyDisablePhoneVerification, constants.EnvKeyDisablePlayGround:
if envValueBool, err := strconv.ParseBool(envValue); err == nil {
if value.(bool) != envValueBool {
storeData[key] = envValueBool

View File

@@ -3,39 +3,51 @@ module github.com/authorizerdev/authorizer/server
go 1.16
require (
github.com/99designs/gqlgen v0.17.20
github.com/arangodb/go-driver v1.2.1
github.com/aws/aws-sdk-go v1.44.109
github.com/coreos/go-oidc/v3 v3.1.0
github.com/couchbase/gocb/v2 v2.6.0
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/99designs/gqlgen v0.17.39
github.com/arangodb/go-driver v1.6.0
github.com/aws/aws-sdk-go v1.45.25
github.com/bytedance/sonic v1.10.2 // indirect
github.com/coreos/go-oidc/v3 v3.6.0
github.com/couchbase/gocb/v2 v2.6.4
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-gonic/gin v1.9.1
github.com/glebarez/sqlite v1.9.0
github.com/go-playground/validator/v10 v10.15.5 // indirect
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/gocql/gocql v1.6.0
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang/protobuf v1.5.2 // 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 // indirect
github.com/robertkrimen/otto v0.0.0-20211024170158-b87d35c0b86f
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.8.0
github.com/vektah/gqlparser/v2 v2.5.1
go.mongodb.org/mongo-driver v1.8.1
golang.org/x/crypto v0.4.0
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.1 // indirect
github.com/google/uuid v1.3.1
github.com/guregu/dynamo v1.20.2
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/joho/godotenv v1.5.1
github.com/klauspost/compress v1.17.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/redis/go-redis/v9 v9.2.1
github.com/robertkrimen/otto v0.2.1
github.com/sirupsen/logrus v1.9.3
github.com/sosodev/duration v1.2.0 // indirect
github.com/stretchr/testify v1.8.4
github.com/twilio/twilio-go v1.14.1
github.com/urfave/cli/v2 v2.25.7 // indirect
github.com/vektah/gqlparser/v2 v2.5.10
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
go.mongodb.org/mongo-driver v1.12.1
golang.org/x/arch v0.5.0 // indirect
golang.org/x/crypto v0.14.0
golang.org/x/oauth2 v0.13.0
golang.org/x/tools v0.14.0 // indirect
google.golang.org/appengine v1.6.8
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/mail.v2 v2.3.1
gopkg.in/square/go-jose.v2 v2.6.0
gorm.io/driver/mysql v1.4.3
gorm.io/driver/postgres v1.4.7
gorm.io/driver/sqlserver v1.4.1
gorm.io/gorm v1.24.2
gorm.io/driver/mysql v1.5.2
gorm.io/driver/postgres v1.5.3
gorm.io/driver/sqlserver v1.5.2
gorm.io/gorm v1.25.5
modernc.org/memory v1.7.2 // indirect
modernc.org/sqlite v1.26.0 // indirect
)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -6,15 +6,15 @@ type AddEmailTemplateRequest struct {
EventName string `json:"event_name"`
Subject string `json:"subject"`
Template string `json:"template"`
Design *string `json:"design"`
Design *string `json:"design,omitempty"`
}
type AddWebhookRequest struct {
EventName string `json:"event_name"`
EventDescription *string `json:"event_description"`
EventDescription *string `json:"event_description,omitempty"`
Endpoint string `json:"endpoint"`
Enabled bool `json:"enabled"`
Headers map[string]interface{} `json:"headers"`
Headers map[string]interface{} `json:"headers,omitempty"`
}
type AdminLoginInput struct {
@@ -27,12 +27,13 @@ type AdminSignupInput struct {
type AuthResponse struct {
Message string `json:"message"`
ShouldShowOtpScreen *bool `json:"should_show_otp_screen"`
AccessToken *string `json:"access_token"`
IDToken *string `json:"id_token"`
RefreshToken *string `json:"refresh_token"`
ExpiresIn *int64 `json:"expires_in"`
User *User `json:"user"`
ShouldShowEmailOtpScreen *bool `json:"should_show_email_otp_screen,omitempty"`
ShouldShowMobileOtpScreen *bool `json:"should_show_mobile_otp_screen,omitempty"`
AccessToken *string `json:"access_token,omitempty"`
IDToken *string `json:"id_token,omitempty"`
RefreshToken *string `json:"refresh_token,omitempty"`
ExpiresIn *int64 `json:"expires_in,omitempty"`
User *User `json:"user,omitempty"`
}
type DeleteEmailTemplateRequest struct {
@@ -49,8 +50,8 @@ type EmailTemplate struct {
Template string `json:"template"`
Design string `json:"design"`
Subject string `json:"subject"`
CreatedAt *int64 `json:"created_at"`
UpdatedAt *int64 `json:"updated_at"`
CreatedAt *int64 `json:"created_at,omitempty"`
UpdatedAt *int64 `json:"updated_at,omitempty"`
}
type EmailTemplates struct {
@@ -59,32 +60,33 @@ type EmailTemplates struct {
}
type Env struct {
AccessTokenExpiryTime *string `json:"ACCESS_TOKEN_EXPIRY_TIME"`
AdminSecret *string `json:"ADMIN_SECRET"`
DatabaseName *string `json:"DATABASE_NAME"`
DatabaseURL *string `json:"DATABASE_URL"`
DatabaseType *string `json:"DATABASE_TYPE"`
DatabaseUsername *string `json:"DATABASE_USERNAME"`
DatabasePassword *string `json:"DATABASE_PASSWORD"`
DatabaseHost *string `json:"DATABASE_HOST"`
DatabasePort *string `json:"DATABASE_PORT"`
AccessTokenExpiryTime *string `json:"ACCESS_TOKEN_EXPIRY_TIME,omitempty"`
AdminSecret *string `json:"ADMIN_SECRET,omitempty"`
DatabaseName *string `json:"DATABASE_NAME,omitempty"`
DatabaseURL *string `json:"DATABASE_URL,omitempty"`
DatabaseType *string `json:"DATABASE_TYPE,omitempty"`
DatabaseUsername *string `json:"DATABASE_USERNAME,omitempty"`
DatabasePassword *string `json:"DATABASE_PASSWORD,omitempty"`
DatabaseHost *string `json:"DATABASE_HOST,omitempty"`
DatabasePort *string `json:"DATABASE_PORT,omitempty"`
ClientID string `json:"CLIENT_ID"`
ClientSecret string `json:"CLIENT_SECRET"`
CustomAccessTokenScript *string `json:"CUSTOM_ACCESS_TOKEN_SCRIPT"`
SMTPHost *string `json:"SMTP_HOST"`
SMTPPort *string `json:"SMTP_PORT"`
SMTPUsername *string `json:"SMTP_USERNAME"`
SMTPPassword *string `json:"SMTP_PASSWORD"`
SMTPLocalName *string `json:"SMTP_LOCAL_NAME"`
SenderEmail *string `json:"SENDER_EMAIL"`
JwtType *string `json:"JWT_TYPE"`
JwtSecret *string `json:"JWT_SECRET"`
JwtPrivateKey *string `json:"JWT_PRIVATE_KEY"`
JwtPublicKey *string `json:"JWT_PUBLIC_KEY"`
AllowedOrigins []string `json:"ALLOWED_ORIGINS"`
AppURL *string `json:"APP_URL"`
RedisURL *string `json:"REDIS_URL"`
ResetPasswordURL *string `json:"RESET_PASSWORD_URL"`
CustomAccessTokenScript *string `json:"CUSTOM_ACCESS_TOKEN_SCRIPT,omitempty"`
SMTPHost *string `json:"SMTP_HOST,omitempty"`
SMTPPort *string `json:"SMTP_PORT,omitempty"`
SMTPUsername *string `json:"SMTP_USERNAME,omitempty"`
SMTPPassword *string `json:"SMTP_PASSWORD,omitempty"`
SMTPLocalName *string `json:"SMTP_LOCAL_NAME,omitempty"`
SenderEmail *string `json:"SENDER_EMAIL,omitempty"`
SenderName *string `json:"SENDER_NAME,omitempty"`
JwtType *string `json:"JWT_TYPE,omitempty"`
JwtSecret *string `json:"JWT_SECRET,omitempty"`
JwtPrivateKey *string `json:"JWT_PRIVATE_KEY,omitempty"`
JwtPublicKey *string `json:"JWT_PUBLIC_KEY,omitempty"`
AllowedOrigins []string `json:"ALLOWED_ORIGINS,omitempty"`
AppURL *string `json:"APP_URL,omitempty"`
RedisURL *string `json:"REDIS_URL,omitempty"`
ResetPasswordURL *string `json:"RESET_PASSWORD_URL,omitempty"`
DisableEmailVerification bool `json:"DISABLE_EMAIL_VERIFICATION"`
DisableBasicAuthentication bool `json:"DISABLE_BASIC_AUTHENTICATION"`
DisableMagicLinkLogin bool `json:"DISABLE_MAGIC_LINK_LOGIN"`
@@ -94,31 +96,32 @@ type Env struct {
DisableStrongPassword bool `json:"DISABLE_STRONG_PASSWORD"`
DisableMultiFactorAuthentication bool `json:"DISABLE_MULTI_FACTOR_AUTHENTICATION"`
EnforceMultiFactorAuthentication bool `json:"ENFORCE_MULTI_FACTOR_AUTHENTICATION"`
Roles []string `json:"ROLES"`
ProtectedRoles []string `json:"PROTECTED_ROLES"`
DefaultRoles []string `json:"DEFAULT_ROLES"`
JwtRoleClaim *string `json:"JWT_ROLE_CLAIM"`
GoogleClientID *string `json:"GOOGLE_CLIENT_ID"`
GoogleClientSecret *string `json:"GOOGLE_CLIENT_SECRET"`
GithubClientID *string `json:"GITHUB_CLIENT_ID"`
GithubClientSecret *string `json:"GITHUB_CLIENT_SECRET"`
FacebookClientID *string `json:"FACEBOOK_CLIENT_ID"`
FacebookClientSecret *string `json:"FACEBOOK_CLIENT_SECRET"`
LinkedinClientID *string `json:"LINKEDIN_CLIENT_ID"`
LinkedinClientSecret *string `json:"LINKEDIN_CLIENT_SECRET"`
AppleClientID *string `json:"APPLE_CLIENT_ID"`
AppleClientSecret *string `json:"APPLE_CLIENT_SECRET"`
TwitterClientID *string `json:"TWITTER_CLIENT_ID"`
TwitterClientSecret *string `json:"TWITTER_CLIENT_SECRET"`
MicrosoftClientID *string `json:"MICROSOFT_CLIENT_ID"`
MicrosoftClientSecret *string `json:"MICROSOFT_CLIENT_SECRET"`
MicrosoftActiveDirectoryTenantID *string `json:"MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID"`
OrganizationName *string `json:"ORGANIZATION_NAME"`
OrganizationLogo *string `json:"ORGANIZATION_LOGO"`
Roles []string `json:"ROLES,omitempty"`
ProtectedRoles []string `json:"PROTECTED_ROLES,omitempty"`
DefaultRoles []string `json:"DEFAULT_ROLES,omitempty"`
JwtRoleClaim *string `json:"JWT_ROLE_CLAIM,omitempty"`
GoogleClientID *string `json:"GOOGLE_CLIENT_ID,omitempty"`
GoogleClientSecret *string `json:"GOOGLE_CLIENT_SECRET,omitempty"`
GithubClientID *string `json:"GITHUB_CLIENT_ID,omitempty"`
GithubClientSecret *string `json:"GITHUB_CLIENT_SECRET,omitempty"`
FacebookClientID *string `json:"FACEBOOK_CLIENT_ID,omitempty"`
FacebookClientSecret *string `json:"FACEBOOK_CLIENT_SECRET,omitempty"`
LinkedinClientID *string `json:"LINKEDIN_CLIENT_ID,omitempty"`
LinkedinClientSecret *string `json:"LINKEDIN_CLIENT_SECRET,omitempty"`
AppleClientID *string `json:"APPLE_CLIENT_ID,omitempty"`
AppleClientSecret *string `json:"APPLE_CLIENT_SECRET,omitempty"`
TwitterClientID *string `json:"TWITTER_CLIENT_ID,omitempty"`
TwitterClientSecret *string `json:"TWITTER_CLIENT_SECRET,omitempty"`
MicrosoftClientID *string `json:"MICROSOFT_CLIENT_ID,omitempty"`
MicrosoftClientSecret *string `json:"MICROSOFT_CLIENT_SECRET,omitempty"`
MicrosoftActiveDirectoryTenantID *string `json:"MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID,omitempty"`
OrganizationName *string `json:"ORGANIZATION_NAME,omitempty"`
OrganizationLogo *string `json:"ORGANIZATION_LOGO,omitempty"`
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"`
DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE,omitempty"`
DefaultAuthorizeResponseMode *string `json:"DEFAULT_AUTHORIZE_RESPONSE_MODE,omitempty"`
DisablePlayground bool `json:"DISABLE_PLAYGROUND"`
}
type Error struct {
@@ -128,8 +131,8 @@ type Error struct {
type ForgotPasswordInput struct {
Email string `json:"email"`
State *string `json:"state"`
RedirectURI *string `json:"redirect_uri"`
State *string `json:"state,omitempty"`
RedirectURI *string `json:"redirect_uri,omitempty"`
}
type GenerateJWTKeysInput struct {
@@ -137,39 +140,45 @@ type GenerateJWTKeysInput struct {
}
type GenerateJWTKeysResponse struct {
Secret *string `json:"secret"`
PublicKey *string `json:"public_key"`
PrivateKey *string `json:"private_key"`
Secret *string `json:"secret,omitempty"`
PublicKey *string `json:"public_key,omitempty"`
PrivateKey *string `json:"private_key,omitempty"`
}
type GetUserRequest struct {
ID string `json:"id"`
ID *string `json:"id,omitempty"`
Email *string `json:"email,omitempty"`
}
type InviteMemberInput struct {
Emails []string `json:"emails"`
RedirectURI *string `json:"redirect_uri"`
RedirectURI *string `json:"redirect_uri,omitempty"`
}
type InviteMembersResponse struct {
Message string `json:"message"`
Users []*User `json:"Users"`
}
type ListWebhookLogRequest struct {
Pagination *PaginationInput `json:"pagination"`
WebhookID *string `json:"webhook_id"`
Pagination *PaginationInput `json:"pagination,omitempty"`
WebhookID *string `json:"webhook_id,omitempty"`
}
type LoginInput struct {
Email string `json:"email"`
Password string `json:"password"`
Roles []string `json:"roles"`
Scope []string `json:"scope"`
State *string `json:"state"`
Roles []string `json:"roles,omitempty"`
Scope []string `json:"scope,omitempty"`
State *string `json:"state,omitempty"`
}
type MagicLinkLoginInput struct {
Email string `json:"email"`
Roles []string `json:"roles"`
Scope []string `json:"scope"`
State *string `json:"state"`
RedirectURI *string `json:"redirect_uri"`
Roles []string `json:"roles,omitempty"`
Scope []string `json:"scope,omitempty"`
State *string `json:"state,omitempty"`
RedirectURI *string `json:"redirect_uri,omitempty"`
}
type Meta struct {
@@ -193,28 +202,29 @@ type Meta struct {
type MobileLoginInput struct {
PhoneNumber string `json:"phone_number"`
Password string `json:"password"`
Roles []string `json:"roles"`
Scope []string `json:"scope"`
State *string `json:"state"`
Roles []string `json:"roles,omitempty"`
Scope []string `json:"scope,omitempty"`
State *string `json:"state,omitempty"`
}
type MobileSignUpInput struct {
Email *string `json:"email"`
GivenName *string `json:"given_name"`
FamilyName *string `json:"family_name"`
MiddleName *string `json:"middle_name"`
Nickname *string `json:"nickname"`
Gender *string `json:"gender"`
Birthdate *string `json:"birthdate"`
Email *string `json:"email,omitempty"`
GivenName *string `json:"given_name,omitempty"`
FamilyName *string `json:"family_name,omitempty"`
MiddleName *string `json:"middle_name,omitempty"`
Nickname *string `json:"nickname,omitempty"`
Gender *string `json:"gender,omitempty"`
Birthdate *string `json:"birthdate,omitempty"`
PhoneNumber string `json:"phone_number"`
Picture *string `json:"picture"`
Picture *string `json:"picture,omitempty"`
Password string `json:"password"`
ConfirmPassword string `json:"confirm_password"`
Roles []string `json:"roles"`
Scope []string `json:"scope"`
RedirectURI *string `json:"redirect_uri"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
State *string `json:"state"`
Roles []string `json:"roles,omitempty"`
Scope []string `json:"scope,omitempty"`
RedirectURI *string `json:"redirect_uri,omitempty"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
State *string `json:"state,omitempty"`
AppData map[string]interface{} `json:"app_data,omitempty"`
}
type OAuthRevokeInput struct {
@@ -222,7 +232,7 @@ type OAuthRevokeInput struct {
}
type PaginatedInput struct {
Pagination *PaginationInput `json:"pagination"`
Pagination *PaginationInput `json:"pagination,omitempty"`
}
type Pagination struct {
@@ -233,19 +243,20 @@ type Pagination struct {
}
type PaginationInput struct {
Limit *int64 `json:"limit"`
Page *int64 `json:"page"`
Limit *int64 `json:"limit,omitempty"`
Page *int64 `json:"page,omitempty"`
}
type ResendOTPRequest struct {
Email string `json:"email"`
State *string `json:"state"`
Email *string `json:"email,omitempty"`
PhoneNumber *string `json:"phone_number,omitempty"`
State *string `json:"state,omitempty"`
}
type ResendVerifyEmailInput struct {
Email string `json:"email"`
Identifier string `json:"identifier"`
State *string `json:"state"`
State *string `json:"state,omitempty"`
}
type ResetPasswordInput struct {
@@ -258,39 +269,50 @@ type Response struct {
Message string `json:"message"`
}
type SMSVerificationRequests struct {
ID string `json:"id"`
Code string `json:"code"`
CodeExpiresAt int64 `json:"code_expires_at"`
PhoneNumber string `json:"phone_number"`
CreatedAt int64 `json:"created_at"`
UpdatedAt *int64 `json:"updated_at,omitempty"`
}
type SessionQueryInput struct {
Roles []string `json:"roles"`
Scope []string `json:"scope"`
Roles []string `json:"roles,omitempty"`
Scope []string `json:"scope,omitempty"`
}
type SignUpInput struct {
Email string `json:"email"`
GivenName *string `json:"given_name"`
FamilyName *string `json:"family_name"`
MiddleName *string `json:"middle_name"`
Nickname *string `json:"nickname"`
Gender *string `json:"gender"`
Birthdate *string `json:"birthdate"`
PhoneNumber *string `json:"phone_number"`
Picture *string `json:"picture"`
GivenName *string `json:"given_name,omitempty"`
FamilyName *string `json:"family_name,omitempty"`
MiddleName *string `json:"middle_name,omitempty"`
Nickname *string `json:"nickname,omitempty"`
Gender *string `json:"gender,omitempty"`
Birthdate *string `json:"birthdate,omitempty"`
PhoneNumber *string `json:"phone_number,omitempty"`
Picture *string `json:"picture,omitempty"`
Password string `json:"password"`
ConfirmPassword string `json:"confirm_password"`
Roles []string `json:"roles"`
Scope []string `json:"scope"`
RedirectURI *string `json:"redirect_uri"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
State *string `json:"state"`
Roles []string `json:"roles,omitempty"`
Scope []string `json:"scope,omitempty"`
RedirectURI *string `json:"redirect_uri,omitempty"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
State *string `json:"state,omitempty"`
AppData map[string]interface{} `json:"app_data,omitempty"`
}
type TestEndpointRequest struct {
Endpoint string `json:"endpoint"`
EventName string `json:"event_name"`
Headers map[string]interface{} `json:"headers"`
EventDescription *string `json:"event_description,omitempty"`
Headers map[string]interface{} `json:"headers,omitempty"`
}
type TestEndpointResponse struct {
HTTPStatus *int64 `json:"http_status"`
Response *string `json:"response"`
HTTPStatus *int64 `json:"http_status,omitempty"`
Response *string `json:"response,omitempty"`
}
type UpdateAccessInput struct {
@@ -299,105 +321,109 @@ type UpdateAccessInput struct {
type UpdateEmailTemplateRequest struct {
ID string `json:"id"`
EventName *string `json:"event_name"`
Template *string `json:"template"`
Subject *string `json:"subject"`
Design *string `json:"design"`
EventName *string `json:"event_name,omitempty"`
Template *string `json:"template,omitempty"`
Subject *string `json:"subject,omitempty"`
Design *string `json:"design,omitempty"`
}
type UpdateEnvInput struct {
AccessTokenExpiryTime *string `json:"ACCESS_TOKEN_EXPIRY_TIME"`
AdminSecret *string `json:"ADMIN_SECRET"`
CustomAccessTokenScript *string `json:"CUSTOM_ACCESS_TOKEN_SCRIPT"`
OldAdminSecret *string `json:"OLD_ADMIN_SECRET"`
SMTPHost *string `json:"SMTP_HOST"`
SMTPPort *string `json:"SMTP_PORT"`
SMTPUsername *string `json:"SMTP_USERNAME"`
SMTPPassword *string `json:"SMTP_PASSWORD"`
SMTPLocalName *string `json:"SMTP_LOCAL_NAME"`
SenderEmail *string `json:"SENDER_EMAIL"`
JwtType *string `json:"JWT_TYPE"`
JwtSecret *string `json:"JWT_SECRET"`
JwtPrivateKey *string `json:"JWT_PRIVATE_KEY"`
JwtPublicKey *string `json:"JWT_PUBLIC_KEY"`
AllowedOrigins []string `json:"ALLOWED_ORIGINS"`
AppURL *string `json:"APP_URL"`
ResetPasswordURL *string `json:"RESET_PASSWORD_URL"`
AppCookieSecure *bool `json:"APP_COOKIE_SECURE"`
AdminCookieSecure *bool `json:"ADMIN_COOKIE_SECURE"`
DisableEmailVerification *bool `json:"DISABLE_EMAIL_VERIFICATION"`
DisableBasicAuthentication *bool `json:"DISABLE_BASIC_AUTHENTICATION"`
DisableMagicLinkLogin *bool `json:"DISABLE_MAGIC_LINK_LOGIN"`
DisableLoginPage *bool `json:"DISABLE_LOGIN_PAGE"`
DisableSignUp *bool `json:"DISABLE_SIGN_UP"`
DisableRedisForEnv *bool `json:"DISABLE_REDIS_FOR_ENV"`
DisableStrongPassword *bool `json:"DISABLE_STRONG_PASSWORD"`
DisableMultiFactorAuthentication *bool `json:"DISABLE_MULTI_FACTOR_AUTHENTICATION"`
EnforceMultiFactorAuthentication *bool `json:"ENFORCE_MULTI_FACTOR_AUTHENTICATION"`
Roles []string `json:"ROLES"`
ProtectedRoles []string `json:"PROTECTED_ROLES"`
DefaultRoles []string `json:"DEFAULT_ROLES"`
JwtRoleClaim *string `json:"JWT_ROLE_CLAIM"`
GoogleClientID *string `json:"GOOGLE_CLIENT_ID"`
GoogleClientSecret *string `json:"GOOGLE_CLIENT_SECRET"`
GithubClientID *string `json:"GITHUB_CLIENT_ID"`
GithubClientSecret *string `json:"GITHUB_CLIENT_SECRET"`
FacebookClientID *string `json:"FACEBOOK_CLIENT_ID"`
FacebookClientSecret *string `json:"FACEBOOK_CLIENT_SECRET"`
LinkedinClientID *string `json:"LINKEDIN_CLIENT_ID"`
LinkedinClientSecret *string `json:"LINKEDIN_CLIENT_SECRET"`
AppleClientID *string `json:"APPLE_CLIENT_ID"`
AppleClientSecret *string `json:"APPLE_CLIENT_SECRET"`
TwitterClientID *string `json:"TWITTER_CLIENT_ID"`
TwitterClientSecret *string `json:"TWITTER_CLIENT_SECRET"`
MicrosoftClientID *string `json:"MICROSOFT_CLIENT_ID"`
MicrosoftClientSecret *string `json:"MICROSOFT_CLIENT_SECRET"`
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"`
AccessTokenExpiryTime *string `json:"ACCESS_TOKEN_EXPIRY_TIME,omitempty"`
AdminSecret *string `json:"ADMIN_SECRET,omitempty"`
CustomAccessTokenScript *string `json:"CUSTOM_ACCESS_TOKEN_SCRIPT,omitempty"`
OldAdminSecret *string `json:"OLD_ADMIN_SECRET,omitempty"`
SMTPHost *string `json:"SMTP_HOST,omitempty"`
SMTPPort *string `json:"SMTP_PORT,omitempty"`
SMTPUsername *string `json:"SMTP_USERNAME,omitempty"`
SMTPPassword *string `json:"SMTP_PASSWORD,omitempty"`
SMTPLocalName *string `json:"SMTP_LOCAL_NAME,omitempty"`
SenderEmail *string `json:"SENDER_EMAIL,omitempty"`
SenderName *string `json:"SENDER_NAME,omitempty"`
JwtType *string `json:"JWT_TYPE,omitempty"`
JwtSecret *string `json:"JWT_SECRET,omitempty"`
JwtPrivateKey *string `json:"JWT_PRIVATE_KEY,omitempty"`
JwtPublicKey *string `json:"JWT_PUBLIC_KEY,omitempty"`
AllowedOrigins []string `json:"ALLOWED_ORIGINS,omitempty"`
AppURL *string `json:"APP_URL,omitempty"`
ResetPasswordURL *string `json:"RESET_PASSWORD_URL,omitempty"`
AppCookieSecure *bool `json:"APP_COOKIE_SECURE,omitempty"`
AdminCookieSecure *bool `json:"ADMIN_COOKIE_SECURE,omitempty"`
DisableEmailVerification *bool `json:"DISABLE_EMAIL_VERIFICATION,omitempty"`
DisableBasicAuthentication *bool `json:"DISABLE_BASIC_AUTHENTICATION,omitempty"`
DisableMagicLinkLogin *bool `json:"DISABLE_MAGIC_LINK_LOGIN,omitempty"`
DisableLoginPage *bool `json:"DISABLE_LOGIN_PAGE,omitempty"`
DisableSignUp *bool `json:"DISABLE_SIGN_UP,omitempty"`
DisableRedisForEnv *bool `json:"DISABLE_REDIS_FOR_ENV,omitempty"`
DisableStrongPassword *bool `json:"DISABLE_STRONG_PASSWORD,omitempty"`
DisableMultiFactorAuthentication *bool `json:"DISABLE_MULTI_FACTOR_AUTHENTICATION,omitempty"`
EnforceMultiFactorAuthentication *bool `json:"ENFORCE_MULTI_FACTOR_AUTHENTICATION,omitempty"`
Roles []string `json:"ROLES,omitempty"`
ProtectedRoles []string `json:"PROTECTED_ROLES,omitempty"`
DefaultRoles []string `json:"DEFAULT_ROLES,omitempty"`
JwtRoleClaim *string `json:"JWT_ROLE_CLAIM,omitempty"`
GoogleClientID *string `json:"GOOGLE_CLIENT_ID,omitempty"`
GoogleClientSecret *string `json:"GOOGLE_CLIENT_SECRET,omitempty"`
GithubClientID *string `json:"GITHUB_CLIENT_ID,omitempty"`
GithubClientSecret *string `json:"GITHUB_CLIENT_SECRET,omitempty"`
FacebookClientID *string `json:"FACEBOOK_CLIENT_ID,omitempty"`
FacebookClientSecret *string `json:"FACEBOOK_CLIENT_SECRET,omitempty"`
LinkedinClientID *string `json:"LINKEDIN_CLIENT_ID,omitempty"`
LinkedinClientSecret *string `json:"LINKEDIN_CLIENT_SECRET,omitempty"`
AppleClientID *string `json:"APPLE_CLIENT_ID,omitempty"`
AppleClientSecret *string `json:"APPLE_CLIENT_SECRET,omitempty"`
TwitterClientID *string `json:"TWITTER_CLIENT_ID,omitempty"`
TwitterClientSecret *string `json:"TWITTER_CLIENT_SECRET,omitempty"`
MicrosoftClientID *string `json:"MICROSOFT_CLIENT_ID,omitempty"`
MicrosoftClientSecret *string `json:"MICROSOFT_CLIENT_SECRET,omitempty"`
MicrosoftActiveDirectoryTenantID *string `json:"MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID,omitempty"`
OrganizationName *string `json:"ORGANIZATION_NAME,omitempty"`
OrganizationLogo *string `json:"ORGANIZATION_LOGO,omitempty"`
DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE,omitempty"`
DefaultAuthorizeResponseMode *string `json:"DEFAULT_AUTHORIZE_RESPONSE_MODE,omitempty"`
DisablePlayground *bool `json:"DISABLE_PLAYGROUND,omitempty"`
}
type UpdateProfileInput struct {
OldPassword *string `json:"old_password"`
NewPassword *string `json:"new_password"`
ConfirmNewPassword *string `json:"confirm_new_password"`
Email *string `json:"email"`
GivenName *string `json:"given_name"`
FamilyName *string `json:"family_name"`
MiddleName *string `json:"middle_name"`
Nickname *string `json:"nickname"`
Gender *string `json:"gender"`
Birthdate *string `json:"birthdate"`
PhoneNumber *string `json:"phone_number"`
Picture *string `json:"picture"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
OldPassword *string `json:"old_password,omitempty"`
NewPassword *string `json:"new_password,omitempty"`
ConfirmNewPassword *string `json:"confirm_new_password,omitempty"`
Email *string `json:"email,omitempty"`
GivenName *string `json:"given_name,omitempty"`
FamilyName *string `json:"family_name,omitempty"`
MiddleName *string `json:"middle_name,omitempty"`
Nickname *string `json:"nickname,omitempty"`
Gender *string `json:"gender,omitempty"`
Birthdate *string `json:"birthdate,omitempty"`
PhoneNumber *string `json:"phone_number,omitempty"`
Picture *string `json:"picture,omitempty"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
AppData map[string]interface{} `json:"app_data,omitempty"`
}
type UpdateUserInput struct {
ID string `json:"id"`
Email *string `json:"email"`
EmailVerified *bool `json:"email_verified"`
GivenName *string `json:"given_name"`
FamilyName *string `json:"family_name"`
MiddleName *string `json:"middle_name"`
Nickname *string `json:"nickname"`
Gender *string `json:"gender"`
Birthdate *string `json:"birthdate"`
PhoneNumber *string `json:"phone_number"`
Picture *string `json:"picture"`
Roles []*string `json:"roles"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
Email *string `json:"email,omitempty"`
EmailVerified *bool `json:"email_verified,omitempty"`
GivenName *string `json:"given_name,omitempty"`
FamilyName *string `json:"family_name,omitempty"`
MiddleName *string `json:"middle_name,omitempty"`
Nickname *string `json:"nickname,omitempty"`
Gender *string `json:"gender,omitempty"`
Birthdate *string `json:"birthdate,omitempty"`
PhoneNumber *string `json:"phone_number,omitempty"`
Picture *string `json:"picture,omitempty"`
Roles []*string `json:"roles,omitempty"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
AppData map[string]interface{} `json:"app_data,omitempty"`
}
type UpdateWebhookRequest struct {
ID string `json:"id"`
EventName *string `json:"event_name"`
EventDescription *string `json:"event_description"`
Endpoint *string `json:"endpoint"`
Enabled *bool `json:"enabled"`
Headers map[string]interface{} `json:"headers"`
EventName *string `json:"event_name,omitempty"`
EventDescription *string `json:"event_description,omitempty"`
Endpoint *string `json:"endpoint,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
Headers map[string]interface{} `json:"headers,omitempty"`
}
type User struct {
@@ -405,21 +431,22 @@ type User struct {
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
SignupMethods string `json:"signup_methods"`
GivenName *string `json:"given_name"`
FamilyName *string `json:"family_name"`
MiddleName *string `json:"middle_name"`
Nickname *string `json:"nickname"`
PreferredUsername *string `json:"preferred_username"`
Gender *string `json:"gender"`
Birthdate *string `json:"birthdate"`
PhoneNumber *string `json:"phone_number"`
PhoneNumberVerified *bool `json:"phone_number_verified"`
Picture *string `json:"picture"`
GivenName *string `json:"given_name,omitempty"`
FamilyName *string `json:"family_name,omitempty"`
MiddleName *string `json:"middle_name,omitempty"`
Nickname *string `json:"nickname,omitempty"`
PreferredUsername *string `json:"preferred_username,omitempty"`
Gender *string `json:"gender,omitempty"`
Birthdate *string `json:"birthdate,omitempty"`
PhoneNumber *string `json:"phone_number,omitempty"`
PhoneNumberVerified *bool `json:"phone_number_verified,omitempty"`
Picture *string `json:"picture,omitempty"`
Roles []string `json:"roles"`
CreatedAt *int64 `json:"created_at"`
UpdatedAt *int64 `json:"updated_at"`
RevokedTimestamp *int64 `json:"revoked_timestamp"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
CreatedAt *int64 `json:"created_at,omitempty"`
UpdatedAt *int64 `json:"updated_at,omitempty"`
RevokedTimestamp *int64 `json:"revoked_timestamp,omitempty"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled,omitempty"`
AppData map[string]interface{} `json:"app_data,omitempty"`
}
type Users struct {
@@ -430,24 +457,34 @@ type Users struct {
type ValidateJWTTokenInput struct {
TokenType string `json:"token_type"`
Token string `json:"token"`
Roles []string `json:"roles"`
Roles []string `json:"roles,omitempty"`
}
type ValidateJWTTokenResponse struct {
IsValid bool `json:"is_valid"`
Claims map[string]interface{} `json:"claims"`
Claims map[string]interface{} `json:"claims,omitempty"`
}
type ValidateSessionInput struct {
Cookie string `json:"cookie"`
Roles []string `json:"roles,omitempty"`
}
type ValidateSessionResponse struct {
IsValid bool `json:"is_valid"`
User *User `json:"user"`
}
type VerificationRequest struct {
ID string `json:"id"`
Identifier *string `json:"identifier"`
Token *string `json:"token"`
Email *string `json:"email"`
Expires *int64 `json:"expires"`
CreatedAt *int64 `json:"created_at"`
UpdatedAt *int64 `json:"updated_at"`
Nonce *string `json:"nonce"`
RedirectURI *string `json:"redirect_uri"`
Identifier *string `json:"identifier,omitempty"`
Token *string `json:"token,omitempty"`
Email *string `json:"email,omitempty"`
Expires *int64 `json:"expires,omitempty"`
CreatedAt *int64 `json:"created_at,omitempty"`
UpdatedAt *int64 `json:"updated_at,omitempty"`
Nonce *string `json:"nonce,omitempty"`
RedirectURI *string `json:"redirect_uri,omitempty"`
}
type VerificationRequests struct {
@@ -457,34 +494,35 @@ type VerificationRequests struct {
type VerifyEmailInput struct {
Token string `json:"token"`
State *string `json:"state"`
State *string `json:"state,omitempty"`
}
type VerifyOTPRequest struct {
Email string `json:"email"`
Email *string `json:"email,omitempty"`
PhoneNumber *string `json:"phone_number,omitempty"`
Otp string `json:"otp"`
State *string `json:"state"`
State *string `json:"state,omitempty"`
}
type Webhook struct {
ID string `json:"id"`
EventName *string `json:"event_name"`
EventDescription *string `json:"event_description"`
Endpoint *string `json:"endpoint"`
Enabled *bool `json:"enabled"`
Headers map[string]interface{} `json:"headers"`
CreatedAt *int64 `json:"created_at"`
UpdatedAt *int64 `json:"updated_at"`
EventName *string `json:"event_name,omitempty"`
EventDescription *string `json:"event_description,omitempty"`
Endpoint *string `json:"endpoint,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
Headers map[string]interface{} `json:"headers,omitempty"`
CreatedAt *int64 `json:"created_at,omitempty"`
UpdatedAt *int64 `json:"updated_at,omitempty"`
}
type WebhookLog struct {
ID string `json:"id"`
HTTPStatus *int64 `json:"http_status"`
Response *string `json:"response"`
Request *string `json:"request"`
WebhookID *string `json:"webhook_id"`
CreatedAt *int64 `json:"created_at"`
UpdatedAt *int64 `json:"updated_at"`
HTTPStatus *int64 `json:"http_status,omitempty"`
Response *string `json:"response,omitempty"`
Request *string `json:"request,omitempty"`
WebhookID *string `json:"webhook_id,omitempty"`
CreatedAt *int64 `json:"created_at,omitempty"`
UpdatedAt *int64 `json:"updated_at,omitempty"`
}
type WebhookLogs struct {

Some files were not shown because too many files have changed in this diff Show More