Merge pull request #1 from authorizerdev/main

Authorizer to foke authorizer
This commit is contained in:
vipul patel 2023-08-29 09:15:53 +05:30 committed by GitHub
commit 11dbe9d97a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
150 changed files with 2274 additions and 1790 deletions

View File

@ -7,5 +7,9 @@ SMTP_PORT=2525
SMTP_USERNAME=test SMTP_USERNAME=test
SMTP_PASSWORD=test SMTP_PASSWORD=test
SENDER_EMAIL="info@authorizer.dev" SENDER_EMAIL="info@authorizer.dev"
TWILIO_API_KEY=test
TWILIO_API_SECRET=test
TWILIO_ACCOUNT_SID=ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
TWILIO_SENDER=909921212112
SENDER_NAME="Authorizer" SENDER_NAME="Authorizer"
AWS_REGION=ap-south-1 AWS_REGION=ap-south-1

58
app/package-lock.json generated
View File

@ -9,7 +9,7 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@authorizerdev/authorizer-react": "^1.1.11", "@authorizerdev/authorizer-react": "^1.1.13",
"@types/react": "^17.0.15", "@types/react": "^17.0.15",
"@types/react-dom": "^17.0.9", "@types/react-dom": "^17.0.9",
"esbuild": "^0.12.17", "esbuild": "^0.12.17",
@ -27,9 +27,9 @@
} }
}, },
"node_modules/@authorizerdev/authorizer-js": { "node_modules/@authorizerdev/authorizer-js": {
"version": "1.2.3", "version": "1.2.6",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.3.tgz", "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz",
"integrity": "sha512-rk/fMRIsqbp+fsy2y09etVjf7CY9/4mG6hf0RKgXgRRfxtAQa1jdkt/De23hBTNeEwAWu6hP/9BQZjcrln6KtA==", "integrity": "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==",
"dependencies": { "dependencies": {
"cross-fetch": "^3.1.5" "cross-fetch": "^3.1.5"
}, },
@ -41,11 +41,11 @@
} }
}, },
"node_modules/@authorizerdev/authorizer-react": { "node_modules/@authorizerdev/authorizer-react": {
"version": "1.1.11", "version": "1.1.13",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.11.tgz", "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz",
"integrity": "sha512-tSI/yjsoeK/RvCOMiHSf1QGOeSpaLYQZEM864LFLndKoJwk7UWCJ86qg1w6ge7B00PmZSNWqST/w5JTcQaVNpw==", "integrity": "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==",
"dependencies": { "dependencies": {
"@authorizerdev/authorizer-js": "^1.2.3" "@authorizerdev/authorizer-js": "^1.2.6"
}, },
"engines": { "engines": {
"node": ">=10" "node": ">=10"
@ -406,11 +406,11 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
}, },
"node_modules/cross-fetch": { "node_modules/cross-fetch": {
"version": "3.1.5", "version": "3.1.8",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==",
"dependencies": { "dependencies": {
"node-fetch": "2.6.7" "node-fetch": "^2.6.12"
} }
}, },
"node_modules/css-color-keywords": { "node_modules/css-color-keywords": {
@ -567,9 +567,9 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"node_modules/node-fetch": { "node_modules/node-fetch": {
"version": "2.6.7", "version": "2.6.12",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
"dependencies": { "dependencies": {
"whatwg-url": "^5.0.0" "whatwg-url": "^5.0.0"
}, },
@ -837,19 +837,19 @@
}, },
"dependencies": { "dependencies": {
"@authorizerdev/authorizer-js": { "@authorizerdev/authorizer-js": {
"version": "1.2.3", "version": "1.2.6",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.3.tgz", "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz",
"integrity": "sha512-rk/fMRIsqbp+fsy2y09etVjf7CY9/4mG6hf0RKgXgRRfxtAQa1jdkt/De23hBTNeEwAWu6hP/9BQZjcrln6KtA==", "integrity": "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA==",
"requires": { "requires": {
"cross-fetch": "^3.1.5" "cross-fetch": "^3.1.5"
} }
}, },
"@authorizerdev/authorizer-react": { "@authorizerdev/authorizer-react": {
"version": "1.1.11", "version": "1.1.13",
"resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.11.tgz", "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz",
"integrity": "sha512-tSI/yjsoeK/RvCOMiHSf1QGOeSpaLYQZEM864LFLndKoJwk7UWCJ86qg1w6ge7B00PmZSNWqST/w5JTcQaVNpw==", "integrity": "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g==",
"requires": { "requires": {
"@authorizerdev/authorizer-js": "^1.2.3" "@authorizerdev/authorizer-js": "^1.2.6"
} }
}, },
"@babel/code-frame": { "@babel/code-frame": {
@ -1144,11 +1144,11 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
}, },
"cross-fetch": { "cross-fetch": {
"version": "3.1.5", "version": "3.1.8",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz",
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", "integrity": "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==",
"requires": { "requires": {
"node-fetch": "2.6.7" "node-fetch": "^2.6.12"
} }
}, },
"css-color-keywords": { "css-color-keywords": {
@ -1270,9 +1270,9 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"node-fetch": { "node-fetch": {
"version": "2.6.7", "version": "2.6.12",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
"requires": { "requires": {
"whatwg-url": "^5.0.0" "whatwg-url": "^5.0.0"
} }

View File

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

View File

@ -2,19 +2,19 @@
# yarn lockfile v1 # yarn lockfile v1
"@authorizerdev/authorizer-js@^1.2.3": "@authorizerdev/authorizer-js@^1.2.6":
"integrity" "sha512-rk/fMRIsqbp+fsy2y09etVjf7CY9/4mG6hf0RKgXgRRfxtAQa1jdkt/De23hBTNeEwAWu6hP/9BQZjcrln6KtA==" "integrity" "sha512-9+9phHUMF+AeDM0y+XQvIRDoerOXnQ1vfTfYN6KxWN1apdrkAd9nzS1zUsA2uJSnX3fFZOErn83GjbYYCYF1BA=="
"resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.3.tgz" "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.6.tgz"
"version" "1.2.3" "version" "1.2.6"
dependencies: dependencies:
"cross-fetch" "^3.1.5" "cross-fetch" "^3.1.5"
"@authorizerdev/authorizer-react@^1.1.11": "@authorizerdev/authorizer-react@^1.1.13":
"integrity" "sha512-tSI/yjsoeK/RvCOMiHSf1QGOeSpaLYQZEM864LFLndKoJwk7UWCJ86qg1w6ge7B00PmZSNWqST/w5JTcQaVNpw==" "integrity" "sha512-LmpzyfR0+nEn+bjUrb/QU9b3kiVoYzMBIvcQ1nV4TNvrvVSqbLPKk+GmoIPkiBEtfy/QSM6XFLkiGNGD9BRP+g=="
"resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.11.tgz" "resolved" "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.13.tgz"
"version" "1.1.11" "version" "1.1.13"
dependencies: dependencies:
"@authorizerdev/authorizer-js" "^1.2.3" "@authorizerdev/authorizer-js" "^1.2.6"
"@babel/code-frame@^7.16.7": "@babel/code-frame@^7.16.7":
"integrity" "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==" "integrity" "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg=="
@ -278,11 +278,11 @@
"version" "1.1.3" "version" "1.1.3"
"cross-fetch@^3.1.5": "cross-fetch@^3.1.5":
"integrity" "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==" "integrity" "sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg=="
"resolved" "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz" "resolved" "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.8.tgz"
"version" "3.1.5" "version" "3.1.8"
dependencies: dependencies:
"node-fetch" "2.6.7" "node-fetch" "^2.6.12"
"css-color-keywords@^1.0.0": "css-color-keywords@^1.0.0":
"integrity" "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" "integrity" "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU="
@ -389,10 +389,10 @@
"resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz"
"version" "2.1.2" "version" "2.1.2"
"node-fetch@2.6.7": "node-fetch@^2.6.12":
"integrity" "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==" "integrity" "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g=="
"resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" "resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz"
"version" "2.6.7" "version" "2.6.12"
dependencies: dependencies:
"whatwg-url" "^5.0.0" "whatwg-url" "^5.0.0"

View File

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

View File

@ -1222,9 +1222,9 @@
dependencies: dependencies:
"is-arrayish" "^0.2.1" "is-arrayish" "^0.2.1"
"esbuild-linux-64@0.14.9": "esbuild-darwin-arm64@0.14.9":
"integrity" "sha512-WoEI+R6/PLZAxS7XagfQMFgRtLUi5cjqqU9VCfo3tnWmAXh/wt8QtUfCVVCcXVwZLS/RNvI19CtfjlrJU61nOg==" "integrity" "sha512-3ue+1T4FR5TaAu4/V1eFMG8Uwn0pgAwQZb/WwL1X78d5Cy8wOVQ67KNH1lsjU+y/9AcwMKZ9x0GGNxBB4a1Rbw=="
"resolved" "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.9.tgz" "resolved" "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.9.tgz"
"version" "0.14.9" "version" "0.14.9"
"esbuild@^0.14.9": "esbuild@^0.14.9":

View File

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

View File

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

View File

@ -66,6 +66,8 @@ const (
EnvKeySenderName = "SENDER_NAME" EnvKeySenderName = "SENDER_NAME"
// EnvKeyIsEmailServiceEnabled key for env variable IS_EMAIL_SERVICE_ENABLED // EnvKeyIsEmailServiceEnabled key for env variable IS_EMAIL_SERVICE_ENABLED
EnvKeyIsEmailServiceEnabled = "IS_EMAIL_SERVICE_ENABLED" EnvKeyIsEmailServiceEnabled = "IS_EMAIL_SERVICE_ENABLED"
// EnvKeyIsSMSServiceEnabled key for env variable IS_SMS_SERVICE_ENABLED
EnvKeyIsSMSServiceEnabled = "IS_SMS_SERVICE_ENABLED"
// EnvKeyAppCookieSecure key for env variable APP_COOKIE_SECURE // EnvKeyAppCookieSecure key for env variable APP_COOKIE_SECURE
EnvKeyAppCookieSecure = "APP_COOKIE_SECURE" EnvKeyAppCookieSecure = "APP_COOKIE_SECURE"
// EnvKeyAdminCookieSecure key for env variable ADMIN_COOKIE_SECURE // EnvKeyAdminCookieSecure key for env variable ADMIN_COOKIE_SECURE
@ -158,6 +160,9 @@ const (
// EnvKeyDisableMultiFactorAuthentication is key for env variable DISABLE_MULTI_FACTOR_AUTHENTICATION // 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 // this variable is used to completely disable multi factor authentication. It will have no effect on profile preference
EnvKeyDisableMultiFactorAuthentication = "DISABLE_MULTI_FACTOR_AUTHENTICATION" 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"
// Slice variables // Slice variables
// EnvKeyRoles key for env variable ROLES // EnvKeyRoles key for env variable ROLES
@ -177,12 +182,13 @@ const (
// This env is used for setting default response mode in authorize handler // This env is used for setting default response mode in authorize handler
EnvKeyDefaultAuthorizeResponseMode = "DEFAULT_AUTHORIZE_RESPONSE_MODE" EnvKeyDefaultAuthorizeResponseMode = "DEFAULT_AUTHORIZE_RESPONSE_MODE"
// Phone verification setting
EnvKeyDisablePhoneVerification = "DISABLE_PHONE_VERIFICATION"
// Twilio env variables // Twilio env variables
// EnvKeyTwilioAPIKey key for env variable TWILIO_API_KEY
EnvKeyTwilioAPIKey = "TWILIO_API_KEY" EnvKeyTwilioAPIKey = "TWILIO_API_KEY"
// EnvKeyTwilioAPISecret key for env variable TWILIO_API_SECRET
EnvKeyTwilioAPISecret = "TWILIO_API_SECRET" EnvKeyTwilioAPISecret = "TWILIO_API_SECRET"
// EnvKeyTwilioAccountSID key for env variable TWILIO_ACCOUNT_SID
EnvKeyTwilioAccountSID = "TWILIO_ACCOUNT_SID" EnvKeyTwilioAccountSID = "TWILIO_ACCOUNT_SID"
EnvKeyTwilioSenderFrom = "TWILIO_SENDER_FROM" // EnvKeyTwilioSender key for env variable TWILIO_SENDER
EnvKeyTwilioSender = "TWILIO_SENDER"
) )

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

@ -1,10 +1,18 @@
package models 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 // OTP model for database
type OTP struct { type OTP struct {
Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb Key string `json:"_key,omitempty" bson:"_key,omitempty" cql:"_key,omitempty" dynamo:"key,omitempty"` // for arangodb
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"` ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
Email string `gorm:"unique" json:"email" bson:"email" cql:"email" dynamo:"email" index:"email,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"` Otp string `json:"otp" bson:"otp" cql:"otp" dynamo:"otp"`
ExpiresAt int64 `json:"expires_at" bson:"expires_at" cql:"expires_at" dynamo:"expires_at"` 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"` CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`

View File

@ -1,11 +0,0 @@
package models
// SMS verification requests model for database
type SMSVerificationRequest struct {
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id" cql:"id" dynamo:"id,hash"`
PhoneNumber string `gorm:"unique" json:"phone_number" bson:"phone_number" cql:"phone_number" dynamo:"phone_number" index:"phone_number,hash"`
Code string `json:"code" bson:"code" cql:"code" dynamo:"code"`
CodeExpiresAt int64 `json:"code_expires_at" bson:"code_expires_at" cql:"code_expires_at" dynamo:"code_expires_at"`
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_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"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled" bson:"is_multi_factor_auth_enabled" cql:"is_multi_factor_auth_enabled" dynamo:"is_multi_factor_auth_enabled"`
UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"` UpdatedAt int64 `json:"updated_at" bson:"updated_at" cql:"updated_at" dynamo:"updated_at"`
CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"` CreatedAt int64 `json:"created_at" bson:"created_at" cql:"created_at" dynamo:"created_at"`
AppData *string `json:"app_data" bson:"app_data" cql:"app_data" dynamo:"app_data"`
} }
func (user *User) AsAPIUser() *model.User { func (user *User) AsAPIUser() *model.User {
isEmailVerified := user.EmailVerifiedAt != nil isEmailVerified := user.EmailVerifiedAt != nil
isPhoneVerified := user.PhoneNumberVerifiedAt != nil isPhoneVerified := user.PhoneNumberVerifiedAt != nil
appDataMap := make(map[string]interface{})
json.Unmarshal([]byte(refs.StringValue(user.AppData)), &appDataMap)
// id := user.ID // id := user.ID
// if strings.Contains(id, Collections.User+"/") { // if strings.Contains(id, Collections.User+"/") {
// id = strings.TrimPrefix(id, Collections.User+"/") // id = strings.TrimPrefix(id, Collections.User+"/")
@ -63,6 +65,7 @@ func (user *User) AsAPIUser() *model.User {
IsMultiFactorAuthEnabled: user.IsMultiFactorAuthEnabled, IsMultiFactorAuthEnabled: user.IsMultiFactorAuthEnabled,
CreatedAt: refs.NewInt64Ref(user.CreatedAt), CreatedAt: refs.NewInt64Ref(user.CreatedAt),
UpdatedAt: refs.NewInt64Ref(user.UpdatedAt), UpdatedAt: refs.NewInt64Ref(user.UpdatedAt),
AppData: appDataMap,
} }
} }

View File

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

View File

@ -12,7 +12,7 @@ import (
) )
// AddEnv to save environment information in database // 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 == "" { if env.ID == "" {
env.ID = uuid.New().String() env.ID = uuid.New().String()
env.Key = env.ID 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 // 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.UpdatedAt = time.Now().Unix()
collection, _ := p.db.Collection(ctx, models.Collections.Env) collection, _ := p.db.Collection(ctx, models.Collections.Env)
meta, err := collection.UpdateDocument(ctx, env.Key, 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 // 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 var env *models.Env
query := fmt.Sprintf("FOR d in %s RETURN d", models.Collections.Env) query := fmt.Sprintf("FOR d in %s RETURN d", models.Collections.Env)
cursor, err := p.db.Query(ctx, query, nil) cursor, err := p.db.Query(ctx, query, nil)
if err != nil { if err != nil {
return env, err return env, err
} }
defer cursor.Close() defer cursor.Close()
for { for {
if !cursor.HasMore() { if !cursor.HasMore() {
if env.Key == "" { if env == nil {
return env, fmt.Errorf("config not found") return env, fmt.Errorf("config not found")
} }
break break

View File

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

View File

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

View File

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

View File

@ -1,23 +0,0 @@
package arangodb
import (
"context"
"github.com/authorizerdev/authorizer/server/db/models"
)
// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
return sms_code, nil
}
func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var sms_verification_request models.SMSVerificationRequest
return &sms_verification_request, nil
}
func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
return nil
}

View File

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

View File

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

View File

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

View File

@ -12,12 +12,11 @@ import (
) )
// AddWebhookLog to add webhook log // 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 == "" { if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String() webhookLog.ID = uuid.New().String()
webhookLog.Key = webhookLog.ID webhookLog.Key = webhookLog.ID
} }
webhookLog.Key = webhookLog.ID webhookLog.Key = webhookLog.ID
webhookLog.CreatedAt = time.Now().Unix() webhookLog.CreatedAt = time.Now().Unix()
webhookLog.UpdatedAt = 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 // 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{} webhookLogs := []*model.WebhookLog{}
bindVariables := map[string]interface{}{} 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) 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 != "" { 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) 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{}{ bindVariables = map[string]interface{}{
"webhook_id": webhookID, "webhook_id": webhookID,
} }
} }
sctx := arangoDriver.WithQueryFullCount(ctx) sctx := arangoDriver.WithQueryFullCount(ctx)
cursor, err := p.db.Query(sctx, query, bindVariables) cursor, err := p.db.Query(sctx, query, bindVariables)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer cursor.Close() defer cursor.Close()
paginationClone := pagination paginationClone := pagination
paginationClone.Total = cursor.Statistics().FullCount() paginationClone.Total = cursor.Statistics().FullCount()
for { for {
var webhookLog models.WebhookLog var webhookLog *models.WebhookLog
meta, err := cursor.ReadDocument(ctx, &webhookLog) meta, err := cursor.ReadDocument(ctx, &webhookLog)
if arangoDriver.IsNoMoreDocuments(err) { if arangoDriver.IsNoMoreDocuments(err) {
break break
} else if err != nil { } else if err != nil {
return nil, err return nil, err
} }
if meta.Key != "" { if meta.Key != "" {
webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog()) webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog())
} }
} }
return &model.WebhookLogs{ return &model.WebhookLogs{
Pagination: &paginationClone, Pagination: paginationClone,
WebhookLogs: webhookLogs, WebhookLogs: webhookLogs,
}, nil }, nil
} }

View File

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

View File

@ -11,11 +11,10 @@ import (
) )
// AddEnv to save environment information in database // 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 == "" { if env.ID == "" {
env.ID = uuid.New().String() env.ID = uuid.New().String()
} }
env.CreatedAt = time.Now().Unix() env.CreatedAt = time.Now().Unix()
env.UpdatedAt = 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) 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 // 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.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) 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() err := p.db.Query(updateEnvQuery).Exec()
if err != nil { 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 // 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 var env models.Env
query := fmt.Sprintf("SELECT id, env, hash, created_at, updated_at FROM %s LIMIT 1", KeySpace+"."+models.Collections.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) err := p.db.Query(query).Consistency(gocql.One).Scan(&env.ID, &env.EnvData, &env.Hash, &env.CreatedAt, &env.UpdatedAt)
if err != nil { if err != nil {
return env, err return nil, err
} }
return &env, nil
return env, nil
} }

View File

@ -2,6 +2,7 @@ package cassandradb
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"time" "time"
@ -12,7 +13,20 @@ import (
// UpsertOTP to add or update otp // UpsertOTP to add or update otp
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { 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 shouldCreate := false
if otp == nil { if otp == nil {
shouldCreate = true shouldCreate = true
@ -20,6 +34,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
ID: uuid.NewString(), ID: uuid.NewString(),
Otp: otpParam.Otp, Otp: otpParam.Otp,
Email: otpParam.Email, Email: otpParam.Email,
PhoneNumber: otpParam.PhoneNumber,
ExpiresAt: otpParam.ExpiresAt, ExpiresAt: otpParam.ExpiresAt,
CreatedAt: time.Now().Unix(), CreatedAt: time.Now().Unix(),
UpdatedAt: 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() otp.UpdatedAt = time.Now().Unix()
query := "" query := ""
if shouldCreate { 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 { } 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) 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 // GetOTPByEmail to get otp for a given email address
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
var otp models.OTP 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) 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.Otp, &otp.ExpiresAt, &otp.CreatedAt, &otp.UpdatedAt) 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 { if err != nil {
return nil, err return nil, err
} }

View File

@ -254,7 +254,19 @@ func NewProvider() (*provider, error) {
if err != nil { if err != nil {
return nil, err 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 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{ return &provider{
db: session, db: session,
}, err }, err

View File

@ -10,14 +10,12 @@ import (
) )
// AddSession to save session information in database // 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 == "" { if session.ID == "" {
session.ID = uuid.New().String() session.ID = uuid.New().String()
} }
session.CreatedAt = time.Now().Unix() session.CreatedAt = time.Now().Unix()
session.UpdatedAt = 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) 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() err := p.db.Query(insertSessionQuery).Exec()
if err != nil { if err != nil {
@ -25,3 +23,8 @@ func (p *provider) AddSession(ctx context.Context, session models.Session) error
} }
return nil return nil
} }
// DeleteSession to delete session information from database
func (p *provider) DeleteSession(ctx context.Context, userId string) error {
return nil
}

View File

@ -1,23 +0,0 @@
package cassandradb
import (
"context"
"github.com/authorizerdev/authorizer/server/db/models"
)
// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
return sms_code, nil
}
func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var sms_verification_request models.SMSVerificationRequest
return &sms_verification_request, nil
}
func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
return nil
}

View File

@ -18,7 +18,7 @@ import (
) )
// AddUser to save user information in database // 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 == "" { if user.ID == "" {
user.ID = uuid.New().String() 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] + ")" values = values[:len(values)-1] + ")"
query := fmt.Sprintf("INSERT INTO %s %s VALUES %s IF NOT EXISTS", KeySpace+"."+models.Collections.User, fields, values) query := fmt.Sprintf("INSERT INTO %s %s VALUES %s IF NOT EXISTS", KeySpace+"."+models.Collections.User, fields, values)
err = p.db.Query(query).Exec() err = p.db.Query(query).Exec()
if err != nil { if err != nil {
return user, err 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 // 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() user.UpdatedAt = time.Now().Unix()
bytes, err := json.Marshal(user) 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 // 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) query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+models.Collections.User, user.ID)
err := p.db.Query(query).Exec() err := p.db.Query(query).Exec()
if err != nil { if err != nil {
return err return err
} }
getSessionsQuery := fmt.Sprintf("SELECT id FROM %s WHERE user_id = '%s' ALLOW FILTERING", KeySpace+"."+models.Collections.Session, user.ID) 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() scanner := p.db.Query(getSessionsQuery).Iter().Scanner()
sessionIDs := "" sessionIDs := ""
@ -167,7 +165,7 @@ func (p *provider) DeleteUser(ctx context.Context, user models.User) error {
} }
// ListUsers to get list of users from database // 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{} responseUsers := []*model.User{}
paginationClone := pagination paginationClone := pagination
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.User) totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.User)
@ -180,7 +178,6 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (
// so we fetch till limit + offset // so we fetch till limit + offset
// and return the results from offset to limit // and return the results from offset to limit
query := fmt.Sprintf("SELECT id, 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, created_at, updated_at FROM %s LIMIT %d", KeySpace+"."+models.Collections.User, pagination.Limit+pagination.Offset)
scanner := p.db.Query(query).Iter().Scanner() scanner := p.db.Query(query).Iter().Scanner()
counter := int64(0) counter := int64(0)
for scanner.Next() { for scanner.Next() {
@ -195,31 +192,31 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (
counter++ counter++
} }
return &model.Users{ return &model.Users{
Pagination: paginationClone,
Users: responseUsers, Users: responseUsers,
Pagination: &paginationClone,
}, nil }, nil
} }
// GetUserByEmail to get user information from database using email address // 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 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) 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) 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)
if err != nil { 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 // 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 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) 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) 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)
if err != nil { 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 // 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.Trim(updateFields, " ")
updateFields = strings.TrimSuffix(updateFields, ",") updateFields = strings.TrimSuffix(updateFields, ",")
query := "" query := ""
if ids != nil && len(ids) > 0 { if len(ids) > 0 {
idsString := "" idsString := ""
for _, id := range ids { for _, id := range ids {
idsString += fmt.Sprintf("'%s', ", id) idsString += fmt.Sprintf("'%s', ", id)

View File

@ -12,7 +12,7 @@ import (
) )
// AddVerification to save verification request in database // 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 == "" { if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String() 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 // 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 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) 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) 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 { if err != nil {
return verificationRequest, err return nil, err
} }
return verificationRequest, nil return &verificationRequest, nil
} }
// GetVerificationRequestByEmail to get verification request by email from database // 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 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) 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) 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 { if err != nil {
return verificationRequest, err return nil, err
} }
return verificationRequest, nil return &verificationRequest, nil
} }
// ListVerificationRequests to get list of verification requests from database // 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 var verificationRequests []*model.VerificationRequest
paginationClone := pagination paginationClone := pagination
totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.VerificationRequest) totalCountQuery := fmt.Sprintf(`SELECT COUNT(*) FROM %s`, KeySpace+"."+models.Collections.VerificationRequest)
err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total) err := p.db.Query(totalCountQuery).Consistency(gocql.One).Scan(&paginationClone.Total)
if err != nil { if err != nil {
return nil, err return nil, err
} }
// there is no offset in cassandra // there is no offset in cassandra
// so we fetch till limit + offset // so we fetch till limit + offset
// and return the results from offset to limit // and return the results from offset to limit
@ -85,12 +83,12 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode
return &model.VerificationRequests{ return &model.VerificationRequests{
VerificationRequests: verificationRequests, VerificationRequests: verificationRequests,
Pagination: &paginationClone, Pagination: paginationClone,
}, nil }, nil
} }
// DeleteVerificationRequest to delete verification request from database // 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) query := fmt.Sprintf("DELETE FROM %s WHERE id = '%s'", KeySpace+"."+models.Collections.VerificationRequest, verificationRequest.ID)
err := p.db.Query(query).Exec() err := p.db.Query(query).Exec()
if err != nil { if err != nil {

View File

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

View File

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

View File

@ -15,7 +15,7 @@ import (
) )
// AddEmailTemplate to add EmailTemplate // 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 == "" { if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String() emailTemplate.ID = uuid.New().String()
@ -37,7 +37,7 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em
} }
// UpdateEmailTemplate to update EmailTemplate // 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) bytes, err := json.Marshal(emailTemplate)
if err != nil { if err != nil {
return nil, err return nil, err
@ -67,7 +67,7 @@ func (p *provider) UpdateEmailTemplate(ctx context.Context, emailTemplate models
} }
// ListEmailTemplates to list EmailTemplate // 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{} emailTemplates := []*model.EmailTemplate{}
paginationClone := pagination paginationClone := pagination
total, err := p.GetTotalDocs(ctx, models.Collections.EmailTemplate) 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() { for queryResult.Next() {
emailTemplate := models.EmailTemplate{} var emailTemplate *models.EmailTemplate
err := queryResult.Row(&emailTemplate) err := queryResult.Row(&emailTemplate)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
@ -102,54 +102,46 @@ func (p *provider) ListEmailTemplate(ctx context.Context, pagination model.Pagin
} }
return &model.EmailTemplates{ return &model.EmailTemplates{
Pagination: &paginationClone, Pagination: paginationClone,
EmailTemplates: emailTemplates, EmailTemplates: emailTemplates,
}, nil }, nil
} }
// GetEmailTemplateByID to get EmailTemplate by id // GetEmailTemplateByID to get EmailTemplate by id
func (p *provider) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) { 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) 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{ q, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx, Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus, ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
PositionalParameters: []interface{}{emailTemplateID}, PositionalParameters: []interface{}{emailTemplateID},
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = q.One(&emailTemplate) err = q.One(&emailTemplate)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return emailTemplate.AsAPIEmailTemplate(), nil return emailTemplate.AsAPIEmailTemplate(), nil
} }
// GetEmailTemplateByEventName to get EmailTemplate by event_name // GetEmailTemplateByEventName to get EmailTemplate by event_name
func (p *provider) GetEmailTemplateByEventName(ctx context.Context, eventName string) (*model.EmailTemplate, error) { 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) 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{ q, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx, Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus, ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
PositionalParameters: []interface{}{eventName}, PositionalParameters: []interface{}{eventName},
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
err = q.One(&emailTemplate) err = q.One(&emailTemplate)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return emailTemplate.AsAPIEmailTemplate(), nil return emailTemplate.AsAPIEmailTemplate(), nil
} }

View File

@ -11,7 +11,7 @@ import (
) )
// AddEnv to save environment information in database // 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 == "" { if env.ID == "" {
env.ID = uuid.New().String() 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.UpdatedAt = time.Now().Unix()
env.Key = env.ID env.Key = env.ID
env.EncryptionKey = env.Hash env.EncryptionKey = env.Hash
insertOpt := gocb.InsertOptions{ insertOpt := gocb.InsertOptions{
Context: ctx, 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 // 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.UpdatedAt = time.Now().Unix()
env.EncryptionKey = env.Hash env.EncryptionKey = env.Hash
@ -40,17 +39,15 @@ func (p *provider) UpdateEnv(ctx context.Context, env models.Env) (models.Env, e
Context: ctx, Context: ctx,
PositionalParameters: []interface{}{env.EnvData, env.UpdatedAt, env.UpdatedAt, env.ID}, PositionalParameters: []interface{}{env.EnvData, env.UpdatedAt, env.UpdatedAt, env.ID},
}) })
if err != nil { if err != nil {
return env, err return env, err
} }
return env, nil return env, nil
} }
// GetEnv to get environment information from database // 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 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) 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{ 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 return env, err
} }
err = q.One(&env) err = q.One(&env)
if err != nil { if err != nil {
return env, err return env, err
} }

View File

@ -2,6 +2,7 @@ package couchbase
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"time" "time"
@ -12,8 +13,20 @@ import (
// UpsertOTP to add or update otp // UpsertOTP to add or update otp
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { 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 shouldCreate := false
if otp == nil { if otp == nil {
shouldCreate = true shouldCreate = true
@ -21,6 +34,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
ID: uuid.NewString(), ID: uuid.NewString(),
Otp: otpParam.Otp, Otp: otpParam.Otp,
Email: otpParam.Email, Email: otpParam.Email,
PhoneNumber: otpParam.PhoneNumber,
ExpiresAt: otpParam.ExpiresAt, ExpiresAt: otpParam.ExpiresAt,
CreatedAt: time.Now().Unix(), CreatedAt: time.Now().Unix(),
UpdatedAt: 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.Otp = otpParam.Otp
otp.ExpiresAt = otpParam.ExpiresAt otp.ExpiresAt = otpParam.ExpiresAt
} }
otp.UpdatedAt = time.Now().Unix() otp.UpdatedAt = time.Now().Unix()
if shouldCreate { if shouldCreate {
insertOpt := gocb.InsertOptions{ 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 // GetOTPByEmail to get otp for a given email address
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
otp := models.OTP{} 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{ q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus, ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
PositionalParameters: []interface{}{emailAddress}, PositionalParameters: []interface{}{emailAddress},
@ -63,11 +76,27 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
return nil, err return nil, err
} }
err = q.One(&otp) err = q.One(&otp)
if err != nil { if err != nil {
return nil, err 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 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) otpIndex1 := fmt.Sprintf("CREATE INDEX OTPEmailIndex ON %s.%s(email)", scopeName, models.Collections.OTP)
indices[models.Collections.OTP] = []string{otpIndex1} 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 return indices
} }

View File

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

View File

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

View File

@ -1,23 +0,0 @@
package couchbase
import (
"context"
"github.com/authorizerdev/authorizer/server/db/models"
)
// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
return sms_code, nil
}
func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var sms_verification_request models.SMSVerificationRequest
return &sms_verification_request, nil
}
func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
return nil
}

View File

@ -15,7 +15,7 @@ import (
) )
// AddUser to save user information in database // 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 == "" { if user.ID == "" {
user.ID = uuid.New().String() 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 // 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() user.UpdatedAt = time.Now().Unix()
unsertOpt := gocb.UpsertOptions{ unsertOpt := gocb.UpsertOptions{
Context: ctx, 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 // 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{ removeOpt := gocb.RemoveOptions{
Context: ctx, 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 // 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{} users := []*model.User{}
paginationClone := pagination 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) 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{ queryResult, err := p.db.Query(userQuery, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus, ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
Context: ctx, Context: ctx,
@ -97,21 +95,20 @@ func (p *provider) ListUsers(ctx context.Context, pagination model.Pagination) (
return nil, err return nil, err
} }
return &model.Users{ return &model.Users{
Pagination: &paginationClone, Pagination: paginationClone,
Users: users, Users: users,
}, nil }, nil
} }
// GetUserByEmail to get user information from database using email address // 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) {
user := models.User{} 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) 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{ q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus, ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
Context: ctx, Context: ctx,
PositionalParameters: []interface{}{email}, PositionalParameters: []interface{}{email},
}) })
if err != nil { if err != nil {
return user, err return user, err
} }
@ -119,13 +116,12 @@ func (p *provider) GetUserByEmail(ctx context.Context, email string) (models.Use
if err != nil { if err != nil {
return user, err return user, err
} }
return user, nil return user, nil
} }
// GetUserByID to get user information from database using user ID // 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) {
user := models.User{} 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) 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{ q, err := p.db.Query(query, &gocb.QueryOptions{
ScanConsistency: gocb.QueryScanConsistencyRequestPlus, ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
@ -139,7 +135,6 @@ func (p *provider) GetUserByID(ctx context.Context, id string) (models.User, err
if err != nil { if err != nil {
return user, err return user, err
} }
return user, nil return user, nil
} }
@ -174,7 +169,6 @@ func (p *provider) UpdateUsers(ctx context.Context, data map[string]interface{},
return err return err
} }
} }
return nil return nil
} }
@ -194,6 +188,5 @@ func (p *provider) GetUserByPhoneNumber(ctx context.Context, phoneNumber string)
if err != nil { if err != nil {
return user, err return user, err
} }
return user, nil return user, nil
} }

View File

@ -13,11 +13,10 @@ import (
) )
// AddVerification to save verification request in database // 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 == "" { if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String() verificationRequest.ID = uuid.New().String()
} }
verificationRequest.Key = verificationRequest.ID verificationRequest.Key = verificationRequest.ID
verificationRequest.CreatedAt = time.Now().Unix() verificationRequest.CreatedAt = time.Now().Unix()
verificationRequest.UpdatedAt = time.Now().Unix() verificationRequest.UpdatedAt = time.Now().Unix()
@ -28,13 +27,12 @@ func (p *provider) AddVerificationRequest(ctx context.Context, verificationReque
if err != nil { if err != nil {
return verificationRequest, err return verificationRequest, err
} }
return verificationRequest, nil return verificationRequest, nil
} }
// GetVerificationRequestByToken to get verification request from database using token // 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) {
verificationRequest := models.VerificationRequest{} var verificationRequest *models.VerificationRequest
params := make(map[string]interface{}, 1) params := make(map[string]interface{}, 1)
params["token"] = token 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) 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 // 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) 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{ 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}, PositionalParameters: []interface{}{email, identifier},
ScanConsistency: gocb.QueryScanConsistencyRequestPlus, ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
}) })
verificationRequest := models.VerificationRequest{}
if err != nil { if err != nil {
return verificationRequest, err return nil, err
} }
var verificationRequest *models.VerificationRequest
err = queryResult.One(&verificationRequest) err = queryResult.One(&verificationRequest)
if err != nil { if err != nil {
return verificationRequest, err 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 // 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 var verificationRequests []*model.VerificationRequest
paginationClone := pagination paginationClone := pagination
total, err := p.GetTotalDocs(ctx, models.Collections.VerificationRequest) total, err := p.GetTotalDocs(ctx, models.Collections.VerificationRequest)
@ -111,12 +106,12 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode
} }
return &model.VerificationRequests{ return &model.VerificationRequests{
VerificationRequests: verificationRequests, VerificationRequests: verificationRequests,
Pagination: &paginationClone, Pagination: paginationClone,
}, nil }, nil
} }
// DeleteVerificationRequest to delete verification request from database // 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{ removeOpt := gocb.RemoveOptions{
Context: ctx, Context: ctx,
} }

View File

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

View File

@ -13,15 +13,13 @@ import (
) )
// AddWebhookLog to add webhook log // 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 == "" { if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String() webhookLog.ID = uuid.New().String()
} }
webhookLog.Key = webhookLog.ID webhookLog.Key = webhookLog.ID
webhookLog.CreatedAt = time.Now().Unix() webhookLog.CreatedAt = time.Now().Unix()
webhookLog.UpdatedAt = time.Now().Unix() webhookLog.UpdatedAt = time.Now().Unix()
insertOpt := gocb.InsertOptions{ insertOpt := gocb.InsertOptions{
Context: ctx, Context: ctx,
} }
@ -29,19 +27,16 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL
if err != nil { if err != nil {
return webhookLog.AsAPIWebhookLog(), err return webhookLog.AsAPIWebhookLog(), err
} }
return webhookLog.AsAPIWebhookLog(), nil return webhookLog.AsAPIWebhookLog(), nil
} }
// ListWebhookLogs to list webhook logs // 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 query string
var err error var err error
webhookLogs := []*model.WebhookLog{} webhookLogs := []*model.WebhookLog{}
params := make(map[string]interface{}, 1) params := make(map[string]interface{}, 1)
paginationClone := pagination paginationClone := pagination
params["webhookID"] = webhookID params["webhookID"] = webhookID
params["offset"] = paginationClone.Offset params["offset"] = paginationClone.Offset
params["limit"] = paginationClone.Limit params["limit"] = paginationClone.Limit
@ -55,13 +50,11 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat
} else { } 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) 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{ queryResult, err := p.db.Query(query, &gocb.QueryOptions{
Context: ctx, Context: ctx,
ScanConsistency: gocb.QueryScanConsistencyRequestPlus, ScanConsistency: gocb.QueryScanConsistencyRequestPlus,
NamedParameters: params, NamedParameters: params,
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -73,13 +66,12 @@ func (p *provider) ListWebhookLogs(ctx context.Context, pagination model.Paginat
} }
webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog()) webhookLogs = append(webhookLogs, webhookLog.AsAPIWebhookLog())
} }
if err := queryResult.Err(); err != nil { if err := queryResult.Err(); err != nil {
return nil, err return nil, err
} }
return &model.WebhookLogs{ return &model.WebhookLogs{
Pagination: &paginationClone, Pagination: paginationClone,
WebhookLogs: webhookLogs, WebhookLogs: webhookLogs,
}, nil }, nil
} }

View File

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

View File

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

View File

@ -11,7 +11,20 @@ import (
// UpsertOTP to add or update otp // UpsertOTP to add or update otp
func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models.OTP, error) { 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 shouldCreate := false
if otp == nil { if otp == nil {
id := uuid.NewString() id := uuid.NewString()
@ -20,6 +33,7 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
Key: id, Key: id,
Otp: otpParam.Otp, Otp: otpParam.Otp,
Email: otpParam.Email, Email: otpParam.Email,
PhoneNumber: otpParam.PhoneNumber,
ExpiresAt: otpParam.ExpiresAt, ExpiresAt: otpParam.ExpiresAt,
CreatedAt: time.Now().Unix(), CreatedAt: time.Now().Unix(),
} }
@ -28,10 +42,8 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
otp.Otp = otpParam.Otp otp.Otp = otpParam.Otp
otp.ExpiresAt = otpParam.ExpiresAt otp.ExpiresAt = otpParam.ExpiresAt
} }
collection := p.db.Table(models.Collections.OTP) collection := p.db.Table(models.Collections.OTP)
otp.UpdatedAt = time.Now().Unix() otp.UpdatedAt = time.Now().Unix()
var err error var err error
if shouldCreate { if shouldCreate {
err = collection.Put(otp).RunWithContext(ctx) err = collection.Put(otp).RunWithContext(ctx)
@ -41,7 +53,6 @@ func (p *provider) UpsertOTP(ctx context.Context, otpParam *models.OTP) (*models
if err != nil { if err != nil {
return nil, err return nil, err
} }
return otp, nil 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) { func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
var otps []models.OTP var otps []models.OTP
var otp models.OTP var otp models.OTP
collection := p.db.Table(models.Collections.OTP) collection := p.db.Table(models.Collections.OTP)
err := collection.Scan().Index("email").Filter("'email' = ?", emailAddress).Limit(1).AllWithContext(ctx, &otps) err := collection.Scan().Index("email").Filter("'email' = ?", emailAddress).Limit(1).AllWithContext(ctx, &otps)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if len(otps) > 0 { if len(otps) > 0 {
otp = otps[0] otp = otps[0]
return &otp, nil 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 // DeleteOTP to delete otp
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error { func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
collection := p.db.Table(models.Collections.OTP) collection := p.db.Table(models.Collections.OTP)
if otp.ID != "" { if otp.ID != "" {
err := collection.Delete("id", otp.ID).RunWithContext(ctx) err := collection.Delete("id", otp.ID).RunWithContext(ctx)
if err != nil { if err != nil {
return err return err
} }
} }
return nil return nil
} }

View File

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

View File

@ -9,13 +9,11 @@ import (
) )
// AddSession to save session information in database // 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) collection := p.db.Table(models.Collections.Session)
if session.ID == "" { if session.ID == "" {
session.ID = uuid.New().String() session.ID = uuid.New().String()
} }
session.CreatedAt = time.Now().Unix() session.CreatedAt = time.Now().Unix()
session.UpdatedAt = time.Now().Unix() session.UpdatedAt = time.Now().Unix()
err := collection.Put(session).RunWithContext(ctx) 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 { func UpdateByHashKey(table dynamo.Table, hashKey string, hashValue string, item interface{}) error {
existingValue, err := dynamo.MarshalItem(item) existingValue, err := dynamo.MarshalItem(item)
var i interface{} var i interface{}
if err != nil { if err != nil {
return err return err
} }
nullableValue, err := dynamodbattribute.MarshalMap(item) nullableValue, err := dynamodbattribute.MarshalMap(item)
if err != nil { if err != nil {
return err return err
} }
u := table.Update(hashKey, hashValue) u := table.Update(hashKey, hashValue)
for k, v := range existingValue { for k, v := range existingValue {
if k == hashKey { if k == hashKey {
@ -26,7 +23,6 @@ func UpdateByHashKey(table dynamo.Table, hashKey string, hashValue string, item
} }
u = u.Set(k, v) u = u.Set(k, v)
} }
for k, v := range nullableValue { for k, v := range nullableValue {
if k == hashKey { if k == hashKey {
continue continue
@ -36,11 +32,9 @@ func UpdateByHashKey(table dynamo.Table, hashKey string, hashValue string, item
u = u.SetNullable(k, v) u = u.SetNullable(k, v)
} }
} }
err = u.Run() err = u.Run()
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }

View File

@ -1,23 +0,0 @@
package dynamodb
import (
"context"
"github.com/authorizerdev/authorizer/server/db/models"
)
// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, sms_code *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
return sms_code, nil
}
func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var sms_verification_request models.SMSVerificationRequest
return &sms_verification_request, nil
}
func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
return nil
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -12,11 +12,10 @@ import (
) )
// AddEnv to save environment information in database // 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 == "" { if env.ID == "" {
env.ID = uuid.New().String() env.ID = uuid.New().String()
} }
env.CreatedAt = time.Now().Unix() env.CreatedAt = time.Now().Unix()
env.UpdatedAt = time.Now().Unix() env.UpdatedAt = time.Now().Unix()
env.Key = env.ID 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 // 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.UpdatedAt = time.Now().Unix()
configCollection := p.db.Collection(models.Collections.Env, options.Collection()) 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()) _, 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 // 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 var env *models.Env
configCollection := p.db.Collection(models.Collections.Env, options.Collection()) configCollection := p.db.Collection(models.Collections.Env, options.Collection())
cursor, err := configCollection.Find(ctx, bson.M{}, options.Find()) cursor, err := configCollection.Find(ctx, bson.M{}, options.Find())
if err != nil { if err != nil {
return env, err return env, err
} }
defer cursor.Close(ctx) defer cursor.Close(ctx)
for cursor.Next(nil) { for cursor.Next(nil) {
err := cursor.Decode(&env) err := cursor.Decode(&env)
if err != nil { if err != nil {
return env, err return env, err
} }
} }
if env == nil {
if env.ID == "" {
return env, fmt.Errorf("config not found") return env, fmt.Errorf("config not found")
} }
return env, nil return env, nil
} }

View File

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

View File

@ -118,10 +118,7 @@ func NewProvider() (*provider, error) {
Options: options.Index().SetUnique(true).SetSparse(true), Options: options.Index().SetUnique(true).SetSparse(true),
}, },
}, options.CreateIndexes()) }, options.CreateIndexes())
otpCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
mongodb.CreateCollection(ctx, models.Collections.SMSVerificationRequest, options.CreateCollection())
smsCollection := mongodb.Collection(models.Collections.SMSVerificationRequest, options.Collection())
smsCollection.Indexes().CreateMany(ctx, []mongo.IndexModel{
{ {
Keys: bson.M{"phone_number": 1}, Keys: bson.M{"phone_number": 1},
Options: options.Index().SetUnique(true).SetSparse(true), Options: options.Index().SetUnique(true).SetSparse(true),

View File

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

View File

@ -1,69 +0,0 @@
package mongodb
import (
"context"
"time"
"github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo/options"
)
// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
smsVerificationRequest, _ := p.GetCodeByPhone(ctx, smsRequest.PhoneNumber)
shouldCreate := false
if smsVerificationRequest == nil {
id := uuid.NewString()
smsVerificationRequest = &models.SMSVerificationRequest{
ID: id,
CreatedAt: time.Now().Unix(),
Code: smsRequest.Code,
PhoneNumber: smsRequest.PhoneNumber,
CodeExpiresAt: smsRequest.CodeExpiresAt,
}
shouldCreate = true
}
smsVerificationRequest.UpdatedAt = time.Now().Unix()
smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection())
var err error
if shouldCreate {
_, err = smsRequestCollection.InsertOne(ctx, smsVerificationRequest)
} else {
_, err = smsRequestCollection.UpdateOne(ctx, bson.M{"phone_number": bson.M{"$eq": smsRequest.PhoneNumber}}, bson.M{"$set": smsVerificationRequest}, options.MergeUpdateOptions())
}
if err != nil {
return nil, err
}
return smsVerificationRequest, nil
}
func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var smsVerificationRequest models.SMSVerificationRequest
smsRequestCollection := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection())
err := smsRequestCollection.FindOne(ctx, bson.M{"phone_number": phoneNumber}).Decode(&smsVerificationRequest)
if err != nil {
return nil, err
}
return &smsVerificationRequest, nil
}
func (p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
smsVerificationRequests := p.db.Collection(models.Collections.SMSVerificationRequest, options.Collection())
_, err := smsVerificationRequests.DeleteOne(nil, bson.M{"_id": smsRequest.ID}, options.Delete())
if err != nil {
return err
}
return nil
}

View File

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

View File

@ -12,7 +12,7 @@ import (
) )
// AddVerification to save verification request in database // 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 == "" { if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String() 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 // 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 var verificationRequest *models.VerificationRequest
verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection()) verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
err := verificationRequestCollection.FindOne(ctx, bson.M{"token": token}).Decode(&verificationRequest) 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 // 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 var verificationRequest *models.VerificationRequest
verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection()) verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
err := verificationRequestCollection.FindOne(ctx, bson.M{"email": email, "identifier": identifier}).Decode(&verificationRequest) 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 // 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 var verificationRequests []*model.VerificationRequest
opts := options.Find() opts := options.Find()
@ -77,7 +77,7 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode
defer cursor.Close(ctx) defer cursor.Close(ctx)
for cursor.Next(ctx) { for cursor.Next(ctx) {
var verificationRequest models.VerificationRequest var verificationRequest *models.VerificationRequest
err := cursor.Decode(&verificationRequest) err := cursor.Decode(&verificationRequest)
if err != nil { if err != nil {
return nil, err return nil, err
@ -87,12 +87,12 @@ func (p *provider) ListVerificationRequests(ctx context.Context, pagination mode
return &model.VerificationRequests{ return &model.VerificationRequests{
VerificationRequests: verificationRequests, VerificationRequests: verificationRequests,
Pagination: &paginationClone, Pagination: paginationClone,
}, nil }, nil
} }
// DeleteVerificationRequest to delete verification request from database // 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()) verificationRequestCollection := p.db.Collection(models.Collections.VerificationRequest, options.Collection())
_, err := verificationRequestCollection.DeleteOne(ctx, bson.M{"_id": verificationRequest.ID}, options.Delete()) _, err := verificationRequestCollection.DeleteOne(ctx, bson.M{"_id": verificationRequest.ID}, options.Delete())
if err != nil { if err != nil {

View File

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

View File

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

View File

@ -10,7 +10,7 @@ import (
) )
// AddEmailTemplate to add EmailTemplate // 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 == "" { if emailTemplate.ID == "" {
emailTemplate.ID = uuid.New().String() emailTemplate.ID = uuid.New().String()
} }
@ -22,13 +22,13 @@ func (p *provider) AddEmailTemplate(ctx context.Context, emailTemplate models.Em
} }
// UpdateEmailTemplate to update EmailTemplate // 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() emailTemplate.UpdatedAt = time.Now().Unix()
return emailTemplate.AsAPIEmailTemplate(), nil return emailTemplate.AsAPIEmailTemplate(), nil
} }
// ListEmailTemplates to list EmailTemplate // 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 return nil, nil
} }

View File

@ -9,7 +9,7 @@ import (
) )
// AddEnv to save environment information in database // 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 == "" { if env.ID == "" {
env.ID = uuid.New().String() 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 // 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.UpdatedAt = time.Now().Unix()
return env, nil return env, nil
} }
// GetEnv to get environment information from database // 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 var env *models.Env
return env, nil return env, nil
} }

View File

@ -16,6 +16,11 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
return nil, nil 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 // DeleteOTP to delete otp
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error { func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
return nil return nil

View File

@ -9,11 +9,10 @@ import (
) )
// AddSession to save session information in database // 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 == "" { if session.ID == "" {
session.ID = uuid.New().String() session.ID = uuid.New().String()
} }
session.CreatedAt = time.Now().Unix() session.CreatedAt = time.Now().Unix()
session.UpdatedAt = time.Now().Unix() session.UpdatedAt = time.Now().Unix()
return nil return nil

View File

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

View File

@ -10,7 +10,7 @@ import (
) )
// AddVerification to save verification request in database // 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 == "" { if verificationRequest.ID == "" {
verificationRequest.ID = uuid.New().String() 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 // 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 var verificationRequest *models.VerificationRequest
return verificationRequest, nil return verificationRequest, nil
} }
// GetVerificationRequestByEmail to get verification request by email from database // 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 var verificationRequest *models.VerificationRequest
return verificationRequest, nil return verificationRequest, nil
} }
// ListVerificationRequests to get list of verification requests from database // 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 return nil, nil
} }
// DeleteVerificationRequest to delete verification request from database // 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 return nil
} }

View File

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

View File

@ -10,7 +10,7 @@ import (
) )
// AddWebhookLog to add webhook log // 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 == "" { if webhookLog.ID == "" {
webhookLog.ID = uuid.New().String() webhookLog.ID = uuid.New().String()
} }
@ -22,6 +22,6 @@ func (p *provider) AddWebhookLog(ctx context.Context, webhookLog models.WebhookL
} }
// ListWebhookLogs to list webhook logs // 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 return nil, nil
} }

View File

@ -9,50 +9,52 @@ import (
type Provider interface { type Provider interface {
// AddUser to save user information in database // 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 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 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 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 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 to get user information from database using phone number
GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error) GetUserByPhoneNumber(ctx context.Context, phoneNumber string) (*models.User, error)
// GetUserByID to get user information from database using user ID // 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 // UpdateUsers to update multiple users, with parameters of user IDs slice
// If ids set to nil / empty all the users will be updated // If ids set to nil / empty all the users will be updated
UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error UpdateUsers(ctx context.Context, data map[string]interface{}, ids []string) error
// AddVerification to save verification request in database // 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 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 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 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 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 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 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 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 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 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 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 // 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 to get webhook by id
GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error) GetWebhookByID(ctx context.Context, webhookID string) (*model.Webhook, error)
// GetWebhookByEventName to get webhook by event_name // GetWebhookByEventName to get webhook by event_name
@ -61,16 +63,16 @@ type Provider interface {
DeleteWebhook(ctx context.Context, webhook *model.Webhook) error DeleteWebhook(ctx context.Context, webhook *model.Webhook) error
// AddWebhookLog to add webhook log // 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 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 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 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 // 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 to get EmailTemplate by id
GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error) GetEmailTemplateByID(ctx context.Context, emailTemplateID string) (*model.EmailTemplate, error)
// GetEmailTemplateByEventName to get EmailTemplate by event_name // GetEmailTemplateByEventName to get EmailTemplate by event_name
@ -82,13 +84,8 @@ type Provider interface {
UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, error) UpsertOTP(ctx context.Context, otp *models.OTP) (*models.OTP, error)
// GetOTPByEmail to get otp for a given email address // GetOTPByEmail to get otp for a given email address
GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) 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 to delete otp
DeleteOTP(ctx context.Context, otp *models.OTP) error DeleteOTP(ctx context.Context, otp *models.OTP) error
// Upsert SMS code request
UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error)
// Get sms code by phone number
GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error)
// Delete sms
DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error
} }

View File

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

View File

@ -9,7 +9,7 @@ import (
) )
// AddEnv to save environment information in database // 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 == "" { if env.ID == "" {
env.ID = uuid.New().String() 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 // 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.UpdatedAt = time.Now().Unix()
result := p.db.Save(&env) result := p.db.Save(&env)
if result.Error != nil { if result.Error != nil {
return env, result.Error 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 // 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 var env *models.Env
result := p.db.First(&env) result := p.db.First(&env)
if result.Error != nil { if result.Error != nil {
return env, result.Error return env, result.Error
} }
return env, nil return env, nil
} }

View File

@ -2,6 +2,7 @@ package sql
import ( import (
"context" "context"
"errors"
"time" "time"
"github.com/authorizerdev/authorizer/server/db/models" "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 == "" { if otp.ID == "" {
otp.ID = uuid.New().String() 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.Key = otp.ID
otp.CreatedAt = time.Now().Unix() otp.CreatedAt = time.Now().Unix()
otp.UpdatedAt = time.Now().Unix() otp.UpdatedAt = time.Now().Unix()
res := p.db.Clauses(clause.OnConflict{ 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"}), DoUpdates: clause.AssignmentColumns([]string{"otp", "expires_at", "updated_at"}),
}).Create(&otp) }).Create(&otp)
if res.Error != nil { 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 // GetOTPByEmail to get otp for a given email address
func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) { func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*models.OTP, error) {
var otp models.OTP var otp models.OTP
result := p.db.Where("email = ?", emailAddress).First(&otp) result := p.db.Where("email = ?", emailAddress).First(&otp)
if result.Error != nil { if result.Error != nil {
return nil, result.Error return nil, result.Error
@ -41,6 +47,16 @@ func (p *provider) GetOTPByEmail(ctx context.Context, emailAddress string) (*mod
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
result := p.db.Where("phone_number = ?", phoneNumber).First(&otp)
if result.Error != nil {
return nil, result.Error
}
return &otp, nil
}
// DeleteOTP to delete otp // DeleteOTP to delete otp
func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error { func (p *provider) DeleteOTP(ctx context.Context, otp *models.OTP) error {
result := p.db.Delete(&models.OTP{ 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) 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{}, &models.SMSVerificationRequest{}) err = sqlDB.AutoMigrate(&models.User{}, &models.VerificationRequest{}, &models.Session{}, &models.Env{}, &models.Webhook{}, &models.WebhookLog{}, &models.EmailTemplate{}, &models.OTP{})
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

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

View File

@ -1,51 +0,0 @@
package sql
import (
"context"
"time"
"github.com/authorizerdev/authorizer/server/db/models"
"github.com/google/uuid"
"gorm.io/gorm/clause"
)
// SMS verification Request
func (p *provider) UpsertSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) (*models.SMSVerificationRequest, error) {
if smsRequest.ID == "" {
smsRequest.ID = uuid.New().String()
}
smsRequest.CreatedAt = time.Now().Unix()
smsRequest.UpdatedAt = time.Now().Unix()
res := p.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "phone_number"}},
DoUpdates: clause.AssignmentColumns([]string{"code", "code_expires_at"}),
}).Create(smsRequest)
if res.Error != nil {
return nil, res.Error
}
return smsRequest, nil
}
// GetOTPByEmail to get otp for a given email address
func (p *provider) GetCodeByPhone(ctx context.Context, phoneNumber string) (*models.SMSVerificationRequest, error) {
var sms_verification_request models.SMSVerificationRequest
result := p.db.Where("phone_number = ?", phoneNumber).First(&sms_verification_request)
if result.Error != nil {
return nil, result.Error
}
return &sms_verification_request, nil
}
func(p *provider) DeleteSMSRequest(ctx context.Context, smsRequest *models.SMSVerificationRequest) error {
result := p.db.Delete(&models.SMSVerificationRequest{
ID: smsRequest.ID,
})
if result.Error != nil {
return result.Error
}
return nil
}

View File

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

View File

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

View File

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

View File

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

View File

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

49
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 // InitEnv to initialize EnvData and through error if required env are not present
func InitAllEnv() error { func InitAllEnv() error {
envData, err := GetEnvData() 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") log.Info("No env data found in db, using local clone of env data")
// get clone of current store // get clone of current store
envData, err = memorystore.Provider.GetEnvStore() envData, err = memorystore.Provider.GetEnvStore()
@ -104,6 +104,13 @@ func InitAllEnv() error {
osDisableStrongPassword := os.Getenv(constants.EnvKeyDisableStrongPassword) osDisableStrongPassword := os.Getenv(constants.EnvKeyDisableStrongPassword)
osEnforceMultiFactorAuthentication := os.Getenv(constants.EnvKeyEnforceMultiFactorAuthentication) osEnforceMultiFactorAuthentication := os.Getenv(constants.EnvKeyEnforceMultiFactorAuthentication)
osDisableMultiFactorAuthentication := os.Getenv(constants.EnvKeyDisableMultiFactorAuthentication) osDisableMultiFactorAuthentication := os.Getenv(constants.EnvKeyDisableMultiFactorAuthentication)
// phone verification var
osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification)
// 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 // os slice vars
osAllowedOrigins := os.Getenv(constants.EnvKeyAllowedOrigins) osAllowedOrigins := os.Getenv(constants.EnvKeyAllowedOrigins)
@ -111,15 +118,6 @@ func InitAllEnv() error {
osDefaultRoles := os.Getenv(constants.EnvKeyDefaultRoles) osDefaultRoles := os.Getenv(constants.EnvKeyDefaultRoles)
osProtectedRoles := os.Getenv(constants.EnvKeyProtectedRoles) osProtectedRoles := os.Getenv(constants.EnvKeyProtectedRoles)
// phone verification var
osDisablePhoneVerification := os.Getenv(constants.EnvKeyDisablePhoneVerification)
// twilio vars
osTwilioApiKey := os.Getenv(constants.EnvKeyTwilioAPIKey)
osTwilioApiSecret := os.Getenv(constants.EnvKeyTwilioAPISecret)
osTwilioAccountSid := os.Getenv(constants.EnvKeyTwilioAccountSID)
osTwilioSenderFrom := os.Getenv(constants.EnvKeyTwilioSenderFrom)
ienv, ok := envData[constants.EnvKeyEnv] ienv, ok := envData[constants.EnvKeyEnv]
if !ok || ienv == "" { if !ok || ienv == "" {
envData[constants.EnvKeyEnv] = osEnv envData[constants.EnvKeyEnv] = osEnv
@ -691,11 +689,11 @@ func InitAllEnv() error {
envData[constants.EnvKeyIsEmailServiceEnabled] = false 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 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") return errors.New("to enable multi factor authentication, please enable email service")
} }
@ -777,29 +775,39 @@ func InitAllEnv() error {
envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode envData[constants.EnvKeyDefaultAuthorizeResponseMode] = osAuthorizeResponseMode
} }
if val, ok := envData[constants.EnvKeyTwilioAPISecret]; !ok || val == "" {
envData[constants.EnvKeyTwilioAPISecret] = osTwilioApiSecret
}
if osTwilioApiSecret != "" && envData[constants.EnvKeyTwilioAPISecret] != osTwilioApiSecret { if osTwilioApiSecret != "" && envData[constants.EnvKeyTwilioAPISecret] != 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 { if osTwilioApiKey != "" && envData[constants.EnvKeyTwilioAPIKey] != 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 { if osTwilioAccountSid != "" && envData[constants.EnvKeyTwilioAccountSID] != osTwilioAccountSid {
envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid envData[constants.EnvKeyTwilioAccountSID] = osTwilioAccountSid
} }
if osTwilioSenderFrom != "" && envData[constants.EnvKeyTwilioSenderFrom] != osTwilioSenderFrom { if val, ok := envData[constants.EnvKeyTwilioSender]; !ok || val == "" {
envData[constants.EnvKeyTwilioSenderFrom] = osTwilioSenderFrom envData[constants.EnvKeyTwilioSender] = osTwilioSender
}
if osTwilioSender != "" && envData[constants.EnvKeyTwilioSender] != osTwilioSender {
envData[constants.EnvKeyTwilioSender] = osTwilioSender
} }
if _, ok := envData[constants.EnvKeyDisablePhoneVerification]; !ok { if _, ok := envData[constants.EnvKeyDisablePhoneVerification]; !ok {
envData[constants.EnvKeyDisablePhoneVerification] = osDisablePhoneVerification == "false" envData[constants.EnvKeyDisablePhoneVerification] = osDisablePhoneVerification == "false"
} }
if osDisablePhoneVerification != "" { if osDisablePhoneVerification != "" {
boolValue, err := strconv.ParseBool(osDisablePhoneVerification) boolValue, err := strconv.ParseBool(osDisablePhoneVerification)
if err != nil { if err != nil {
return err return err
} }
@ -808,6 +816,15 @@ func InitAllEnv() error {
} }
} }
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
}
err = memorystore.Provider.UpdateEnvStore(envData) err = memorystore.Provider.UpdateEnvStore(envData)
if err != nil { if err != nil {
log.Debug("Error while updating env store: ", err) log.Debug("Error while updating env store: ", err)

View File

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

View File

@ -5,7 +5,7 @@ go 1.16
require ( require (
github.com/99designs/gqlgen v0.17.20 github.com/99designs/gqlgen v0.17.20
github.com/arangodb/go-driver v1.2.1 github.com/arangodb/go-driver v1.2.1
github.com/aws/aws-sdk-go v1.44.109 github.com/aws/aws-sdk-go v1.44.298
github.com/coreos/go-oidc/v3 v3.1.0 github.com/coreos/go-oidc/v3 v3.1.0
github.com/couchbase/gocb/v2 v2.6.0 github.com/couchbase/gocb/v2 v2.6.0
github.com/gin-gonic/gin v1.8.1 github.com/gin-gonic/gin v1.8.1
@ -17,7 +17,7 @@ require (
github.com/golang/protobuf v1.5.2 // indirect github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.6 // indirect github.com/google/go-cmp v0.5.6 // indirect
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/guregu/dynamo v1.16.0 github.com/guregu/dynamo v1.20.0
github.com/joho/godotenv v1.3.0 github.com/joho/godotenv v1.3.0
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect
@ -30,7 +30,7 @@ require (
go.mongodb.org/mongo-driver v1.8.1 go.mongodb.org/mongo-driver v1.8.1
golang.org/x/crypto v0.4.0 golang.org/x/crypto v0.4.0
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914 golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7
google.golang.org/protobuf v1.28.1 // indirect google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/mail.v2 v2.3.1 gopkg.in/mail.v2 v2.3.1

View File

@ -51,9 +51,8 @@ github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e h1:Xg+hGrY2
github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho= github.com/arangodb/go-velocypack v0.0.0-20200318135517-5af53c29c67e/go.mod h1:mq7Shfa/CaixoDxiyAAc5jZ6CVBAyPaNQCGS7mkj4Ho=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/aws/aws-sdk-go v1.42.47/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc= github.com/aws/aws-sdk-go v1.44.298 h1:5qTxdubgV7PptZJmp/2qDwD2JL187ePL7VOxsSh1i3g=
github.com/aws/aws-sdk-go v1.44.109 h1:+Na5JPeS0kiEHoBp5Umcuuf+IDqXqD0lXnM920E31YI= github.com/aws/aws-sdk-go v1.44.298/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go v1.44.109/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A= github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
@ -63,8 +62,8 @@ github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao=
github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w= github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cenkalti/backoff/v4 v4.1.2 h1:6Yo7N8UP2K6LWZnW94DLVSSrbobcWdVzAYOisuDPIFo= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@ -130,8 +129,6 @@ github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk=
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gocql/gocql v1.2.0 h1:TZhsCd7fRuye4VyHr3WCvWwIQaZUmjsqnSIXK9FcVCE= github.com/gocql/gocql v1.2.0 h1:TZhsCd7fRuye4VyHr3WCvWwIQaZUmjsqnSIXK9FcVCE=
github.com/gocql/gocql v1.2.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= github.com/gocql/gocql v1.2.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8=
github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
@ -206,8 +203,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/guregu/dynamo v1.16.0 h1:gmI8oi1VHwYQtq7+RPBeOiSssVLgxH/Az2t+NtDtL2c= github.com/guregu/dynamo v1.20.0 h1:PDdVVhRSXQFFIHlkhoKF6D8kiwI9IU6uUdz/fF6Iiy4=
github.com/guregu/dynamo v1.16.0/go.mod h1:W2Gqcf3MtkrS+Q6fHPGAmRtT0Dyq+TGrqfqrUC9+R/c= github.com/guregu/dynamo v1.20.0/go.mod h1:YQ92BTYVSMIKpFEzhaVqmCJnnSIGxbNF5zvECUaEZRE=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@ -438,12 +435,12 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -462,8 +459,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7 h1:ZrnxWX62AgTKOSagEqxvb3ffipvEDX2pl7E1TdqLqIc=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -508,12 +506,16 @@ golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -523,8 +525,10 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,8 @@ type AdminSignupInput struct {
type AuthResponse struct { type AuthResponse struct {
Message string `json:"message"` Message string `json:"message"`
ShouldShowOtpScreen *bool `json:"should_show_otp_screen"` ShouldShowEmailOtpScreen *bool `json:"should_show_email_otp_screen"`
ShouldShowMobileOtpScreen *bool `json:"should_show_mobile_otp_screen"`
AccessToken *string `json:"access_token"` AccessToken *string `json:"access_token"`
IDToken *string `json:"id_token"` IDToken *string `json:"id_token"`
RefreshToken *string `json:"refresh_token"` RefreshToken *string `json:"refresh_token"`
@ -120,7 +121,6 @@ type Env struct {
AdminCookieSecure bool `json:"ADMIN_COOKIE_SECURE"` AdminCookieSecure bool `json:"ADMIN_COOKIE_SECURE"`
DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE"` DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE"`
DefaultAuthorizeResponseMode *string `json:"DEFAULT_AUTHORIZE_RESPONSE_MODE"` DefaultAuthorizeResponseMode *string `json:"DEFAULT_AUTHORIZE_RESPONSE_MODE"`
SmsCodeExpiryTime *string `json:"SMS_CODE_EXPIRY_TIME"`
} }
type Error struct { type Error struct {
@ -223,6 +223,7 @@ type MobileSignUpInput struct {
RedirectURI *string `json:"redirect_uri"` RedirectURI *string `json:"redirect_uri"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
State *string `json:"state"` State *string `json:"state"`
AppData map[string]interface{} `json:"app_data"`
} }
type OAuthRevokeInput struct { type OAuthRevokeInput struct {
@ -246,7 +247,8 @@ type PaginationInput struct {
} }
type ResendOTPRequest struct { type ResendOTPRequest struct {
Email string `json:"email"` Email *string `json:"email"`
PhoneNumber *string `json:"phone_number"`
State *string `json:"state"` State *string `json:"state"`
} }
@ -297,11 +299,13 @@ type SignUpInput struct {
RedirectURI *string `json:"redirect_uri"` RedirectURI *string `json:"redirect_uri"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
State *string `json:"state"` State *string `json:"state"`
AppData map[string]interface{} `json:"app_data"`
} }
type TestEndpointRequest struct { type TestEndpointRequest struct {
Endpoint string `json:"endpoint"` Endpoint string `json:"endpoint"`
EventName string `json:"event_name"` EventName string `json:"event_name"`
EventDescription *string `json:"event_description"`
Headers map[string]interface{} `json:"headers"` Headers map[string]interface{} `json:"headers"`
} }
@ -391,6 +395,7 @@ type UpdateProfileInput struct {
PhoneNumber *string `json:"phone_number"` PhoneNumber *string `json:"phone_number"`
Picture *string `json:"picture"` Picture *string `json:"picture"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
AppData map[string]interface{} `json:"app_data"`
} }
type UpdateUserInput struct { type UpdateUserInput struct {
@ -407,6 +412,7 @@ type UpdateUserInput struct {
Picture *string `json:"picture"` Picture *string `json:"picture"`
Roles []*string `json:"roles"` Roles []*string `json:"roles"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
AppData map[string]interface{} `json:"app_data"`
} }
type UpdateWebhookRequest struct { type UpdateWebhookRequest struct {
@ -438,6 +444,7 @@ type User struct {
UpdatedAt *int64 `json:"updated_at"` UpdatedAt *int64 `json:"updated_at"`
RevokedTimestamp *int64 `json:"revoked_timestamp"` RevokedTimestamp *int64 `json:"revoked_timestamp"`
IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"` IsMultiFactorAuthEnabled *bool `json:"is_multi_factor_auth_enabled"`
AppData map[string]interface{} `json:"app_data"`
} }
type Users struct { type Users struct {
@ -456,6 +463,16 @@ type ValidateJWTTokenResponse struct {
Claims map[string]interface{} `json:"claims"` Claims map[string]interface{} `json:"claims"`
} }
type ValidateSessionInput struct {
Cookie string `json:"cookie"`
Roles []string `json:"roles"`
}
type ValidateSessionResponse struct {
IsValid bool `json:"is_valid"`
User *User `json:"user"`
}
type VerificationRequest struct { type VerificationRequest struct {
ID string `json:"id"` ID string `json:"id"`
Identifier *string `json:"identifier"` Identifier *string `json:"identifier"`
@ -478,13 +495,9 @@ type VerifyEmailInput struct {
State *string `json:"state"` State *string `json:"state"`
} }
type VerifyMobileRequest struct {
PhoneNumber string `json:"phone_number"`
Code string `json:"code"`
}
type VerifyOTPRequest struct { type VerifyOTPRequest struct {
Email string `json:"email"` Email *string `json:"email"`
PhoneNumber *string `json:"phone_number"`
Otp string `json:"otp"` Otp string `json:"otp"`
State *string `json:"state"` State *string `json:"state"`
} }

View File

@ -51,6 +51,7 @@ type User {
updated_at: Int64 updated_at: Int64
revoked_timestamp: Int64 revoked_timestamp: Int64
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
app_data: Map
} }
type Users { type Users {
@ -84,11 +85,6 @@ type SMSVerificationRequests {
updated_at: Int64 updated_at: Int64
} }
input VerifyMobileRequest {
phone_number: String!
code: String!
}
type Error { type Error {
message: String! message: String!
reason: String! reason: String!
@ -96,7 +92,8 @@ type Error {
type AuthResponse { type AuthResponse {
message: String! message: String!
should_show_otp_screen: Boolean should_show_email_otp_screen: Boolean
should_show_mobile_otp_screen: Boolean
access_token: String access_token: String
id_token: String id_token: String
refresh_token: String refresh_token: String
@ -182,6 +179,11 @@ type ValidateJWTTokenResponse {
claims: Map claims: Map
} }
type ValidateSessionResponse {
is_valid: Boolean!
user: User!
}
type GenerateJWTKeysResponse { type GenerateJWTKeysResponse {
secret: String secret: String
public_key: String public_key: String
@ -322,6 +324,7 @@ input MobileSignUpInput {
# it is used to get code for an on-going auth process during login # it is used to get code for an on-going auth process during login
# and use that code for setting `c_hash` in id_token # and use that code for setting `c_hash` in id_token
state: String state: String
app_data: Map
} }
input SignUpInput { input SignUpInput {
@ -344,6 +347,7 @@ input SignUpInput {
# it is used to get code for an on-going auth process during login # it is used to get code for an on-going auth process during login
# and use that code for setting `c_hash` in id_token # and use that code for setting `c_hash` in id_token
state: String state: String
app_data: Map
} }
input LoginInput { input LoginInput {
@ -399,6 +403,7 @@ input UpdateProfileInput {
phone_number: String phone_number: String
picture: String picture: String
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
app_data: Map
} }
input UpdateUserInput { input UpdateUserInput {
@ -415,6 +420,7 @@ input UpdateUserInput {
picture: String picture: String
roles: [String] roles: [String]
is_multi_factor_auth_enabled: Boolean is_multi_factor_auth_enabled: Boolean
app_data: Map
} }
input ForgotPasswordInput { input ForgotPasswordInput {
@ -474,6 +480,11 @@ input ValidateJWTTokenInput {
roles: [String!] roles: [String!]
} }
input ValidateSessionInput {
cookie: String!
roles: [String!]
}
input GenerateJWTKeysInput { input GenerateJWTKeysInput {
type: String! type: String!
} }
@ -507,6 +518,7 @@ input WebhookRequest {
input TestEndpointRequest { input TestEndpointRequest {
endpoint: String! endpoint: String!
event_name: String! event_name: String!
event_description: String
headers: Map headers: Map
} }
@ -534,7 +546,9 @@ input DeleteEmailTemplateRequest {
} }
input VerifyOTPRequest { input VerifyOTPRequest {
email: String! # either email or phone_number is required
email: String
phone_number: String
otp: String! otp: String!
# state is used for authorization code grant flow # state is used for authorization code grant flow
# it is used to get code for an on-going auth process during login # it is used to get code for an on-going auth process during login
@ -543,7 +557,8 @@ input VerifyOTPRequest {
} }
input ResendOTPRequest { input ResendOTPRequest {
email: String! email: String
phone_number: String
# state is used for authorization code grant flow # state is used for authorization code grant flow
# it is used to get code for an on-going auth process during login # it is used to get code for an on-going auth process during login
# and use that code for setting `c_hash` in id_token # and use that code for setting `c_hash` in id_token
@ -570,7 +585,6 @@ type Mutation {
revoke(params: OAuthRevokeInput!): Response! revoke(params: OAuthRevokeInput!): Response!
verify_otp(params: VerifyOTPRequest!): AuthResponse! verify_otp(params: VerifyOTPRequest!): AuthResponse!
resend_otp(params: ResendOTPRequest!): Response! resend_otp(params: ResendOTPRequest!): Response!
verify_mobile(params: VerifyMobileRequest!): AuthResponse!
# admin only apis # admin only apis
_delete_user(params: DeleteUserInput!): Response! _delete_user(params: DeleteUserInput!): Response!
_update_user(params: UpdateUserInput!): User! _update_user(params: UpdateUserInput!): User!
@ -596,6 +610,7 @@ type Query {
session(params: SessionQueryInput): AuthResponse! session(params: SessionQueryInput): AuthResponse!
profile: User! profile: User!
validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse! validate_jwt_token(params: ValidateJWTTokenInput!): ValidateJWTTokenResponse!
validate_session(params: ValidateSessionInput): ValidateSessionResponse!
# admin only apis # admin only apis
_users(params: PaginatedInput): Users! _users(params: PaginatedInput): Users!
_user(params: GetUserRequest!): User! _user(params: GetUserRequest!): User!

View File

@ -81,11 +81,6 @@ func (r *mutationResolver) ResendOtp(ctx context.Context, params model.ResendOTP
return resolvers.ResendOTPResolver(ctx, params) return resolvers.ResendOTPResolver(ctx, params)
} }
// VerifyMobile is the resolver for the verify_mobile field.
func (r *mutationResolver) VerifyMobile(ctx context.Context, params model.VerifyMobileRequest) (*model.AuthResponse, error) {
return resolvers.VerifyMobileResolver(ctx, params)
}
// DeleteUser is the resolver for the _delete_user field. // DeleteUser is the resolver for the _delete_user field.
func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) { func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
return resolvers.DeleteUserResolver(ctx, params) return resolvers.DeleteUserResolver(ctx, params)
@ -191,6 +186,11 @@ func (r *queryResolver) ValidateJwtToken(ctx context.Context, params model.Valid
return resolvers.ValidateJwtTokenResolver(ctx, params) return resolvers.ValidateJwtTokenResolver(ctx, params)
} }
// ValidateSession is the resolver for the validate_session field.
func (r *queryResolver) ValidateSession(ctx context.Context, params *model.ValidateSessionInput) (*model.ValidateSessionResponse, error) {
return resolvers.ValidateSessionResolver(ctx, params)
}
// Users is the resolver for the _users field. // Users is the resolver for the _users field.
func (r *queryResolver) Users(ctx context.Context, params *model.PaginatedInput) (*model.Users, error) { func (r *queryResolver) Users(ctx context.Context, params *model.PaginatedInput) (*model.Users, error) {
return resolvers.UsersResolver(ctx, params) return resolvers.UsersResolver(ctx, params)

View File

@ -32,11 +32,11 @@ func OAuthCallbackHandler() gin.HandlerFunc {
return func(ctx *gin.Context) { return func(ctx *gin.Context) {
provider := ctx.Param("oauth_provider") provider := ctx.Param("oauth_provider")
state := ctx.Request.FormValue("state") state := ctx.Request.FormValue("state")
sessionState, err := memorystore.Provider.GetState(state) sessionState, err := memorystore.Provider.GetState(state)
if sessionState == "" || err != nil { if sessionState == "" || err != nil {
log.Debug("Invalid oauth state: ", state) log.Debug("Invalid oauth state: ", state)
ctx.JSON(400, gin.H{"error": "invalid oauth state"}) ctx.JSON(400, gin.H{"error": "invalid oauth state"})
return
} }
// contains random token, redirect url, role // contains random token, redirect url, role
sessionSplit := strings.Split(state, "___") sessionSplit := strings.Split(state, "___")
@ -46,32 +46,34 @@ func OAuthCallbackHandler() gin.HandlerFunc {
ctx.JSON(400, gin.H{"error": "invalid redirect url"}) ctx.JSON(400, gin.H{"error": "invalid redirect url"})
return return
} }
// remove state from store // remove state from store
go memorystore.Provider.RemoveState(state) go memorystore.Provider.RemoveState(state)
stateValue := sessionSplit[0] stateValue := sessionSplit[0]
redirectURL := sessionSplit[1] redirectURL := sessionSplit[1]
inputRoles := strings.Split(sessionSplit[2], ",") inputRoles := strings.Split(sessionSplit[2], ",")
scopes := strings.Split(sessionSplit[3], ",") scopes := strings.Split(sessionSplit[3], ",")
var user *models.User
user := models.User{}
oauthCode := ctx.Request.FormValue("code") oauthCode := ctx.Request.FormValue("code")
if oauthCode == "" {
log.Debug("Invalid oauth code: ", oauthCode)
ctx.JSON(400, gin.H{"error": "invalid oauth code"})
return
}
switch provider { switch provider {
case constants.AuthRecipeMethodGoogle: case constants.AuthRecipeMethodGoogle:
user, err = processGoogleUserInfo(oauthCode) user, err = processGoogleUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodGithub: case constants.AuthRecipeMethodGithub:
user, err = processGithubUserInfo(oauthCode) user, err = processGithubUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodFacebook: case constants.AuthRecipeMethodFacebook:
user, err = processFacebookUserInfo(oauthCode) user, err = processFacebookUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodLinkedIn: case constants.AuthRecipeMethodLinkedIn:
user, err = processLinkedInUserInfo(oauthCode) user, err = processLinkedInUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodApple: case constants.AuthRecipeMethodApple:
user, err = processAppleUserInfo(oauthCode) user, err = processAppleUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodTwitter: case constants.AuthRecipeMethodTwitter:
user, err = processTwitterUserInfo(oauthCode, sessionState) user, err = processTwitterUserInfo(ctx, oauthCode, sessionState)
case constants.AuthRecipeMethodMicrosoft: case constants.AuthRecipeMethodMicrosoft:
user, err = processMicrosoftUserInfo(oauthCode) user, err = processMicrosoftUserInfo(ctx, oauthCode)
default: default:
log.Info("Invalid oauth provider") log.Info("Invalid oauth provider")
err = fmt.Errorf(`invalid oauth provider`) err = fmt.Errorf(`invalid oauth provider`)
@ -260,10 +262,12 @@ func OAuthCallbackHandler() gin.HandlerFunc {
go func() { go func() {
if isSignUp { if isSignUp {
utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, provider, user) utils.RegisterEvent(ctx, constants.UserSignUpWebhookEvent, provider, user)
// User is also logged in with signup
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user)
} else { } else {
utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user) utils.RegisterEvent(ctx, constants.UserLoginWebhookEvent, provider, user)
} }
db.Provider.AddSession(ctx, models.Session{ db.Provider.AddSession(ctx, &models.Session{
UserID: user.ID, UserID: user.ID,
UserAgent: utils.GetUserAgent(ctx.Request), UserAgent: utils.GetUserAgent(ctx.Request),
IP: utils.GetIP(ctx.Request), IP: utils.GetIP(ctx.Request),
@ -279,15 +283,13 @@ func OAuthCallbackHandler() gin.HandlerFunc {
} }
} }
func processGoogleUserInfo(code string) (models.User, error) { func processGoogleUserInfo(ctx context.Context, code string) (*models.User, error) {
user := models.User{} var user *models.User
ctx := context.Background()
oauth2Token, err := oauth.OAuthProviders.GoogleConfig.Exchange(ctx, code) oauth2Token, err := oauth.OAuthProviders.GoogleConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid google exchange code: %s", err.Error()) return user, fmt.Errorf("invalid google exchange code: %s", err.Error())
} }
verifier := oauth.OIDCProviders.GoogleOIDC.Verifier(&oidc.Config{ClientID: oauth.OAuthProviders.GoogleConfig.ClientID}) verifier := oauth.OIDCProviders.GoogleOIDC.Verifier(&oidc.Config{ClientID: oauth.OAuthProviders.GoogleConfig.ClientID})
// Extract the ID Token from OAuth2 token. // Extract the ID Token from OAuth2 token.
@ -312,9 +314,9 @@ func processGoogleUserInfo(code string) (models.User, error) {
return user, nil return user, nil
} }
func processGithubUserInfo(code string) (models.User, error) { func processGithubUserInfo(ctx context.Context, code string) (*models.User, error) {
user := models.User{} var user *models.User
oauth2Token, err := oauth.OAuthProviders.GithubConfig.Exchange(context.TODO(), code) oauth2Token, err := oauth.OAuthProviders.GithubConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid github exchange code: %s", err.Error()) return user, fmt.Errorf("invalid github exchange code: %s", err.Error())
@ -409,7 +411,7 @@ func processGithubUserInfo(code string) (models.User, error) {
} }
} }
user = models.User{ user = &models.User{
GivenName: &firstName, GivenName: &firstName,
FamilyName: &lastName, FamilyName: &lastName,
Picture: &picture, Picture: &picture,
@ -419,9 +421,9 @@ func processGithubUserInfo(code string) (models.User, error) {
return user, nil return user, nil
} }
func processFacebookUserInfo(code string) (models.User, error) { func processFacebookUserInfo(ctx context.Context, code string) (*models.User, error) {
user := models.User{} var user *models.User
oauth2Token, err := oauth.OAuthProviders.FacebookConfig.Exchange(context.TODO(), code) oauth2Token, err := oauth.OAuthProviders.FacebookConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Invalid facebook exchange code: ", err) log.Debug("Invalid facebook exchange code: ", err)
return user, fmt.Errorf("invalid facebook exchange code: %s", err.Error()) return user, fmt.Errorf("invalid facebook exchange code: %s", err.Error())
@ -460,7 +462,7 @@ func processFacebookUserInfo(code string) (models.User, error) {
lastName := fmt.Sprintf("%v", userRawData["last_name"]) lastName := fmt.Sprintf("%v", userRawData["last_name"])
picture := fmt.Sprintf("%v", picDataObject["url"]) picture := fmt.Sprintf("%v", picDataObject["url"])
user = models.User{ user = &models.User{
GivenName: &firstName, GivenName: &firstName,
FamilyName: &lastName, FamilyName: &lastName,
Picture: &picture, Picture: &picture,
@ -470,9 +472,9 @@ func processFacebookUserInfo(code string) (models.User, error) {
return user, nil return user, nil
} }
func processLinkedInUserInfo(code string) (models.User, error) { func processLinkedInUserInfo(ctx context.Context, code string) (*models.User, error) {
user := models.User{} var user *models.User
oauth2Token, err := oauth.OAuthProviders.LinkedInConfig.Exchange(context.TODO(), code) oauth2Token, err := oauth.OAuthProviders.LinkedInConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid linkedin exchange code: %s", err.Error()) return user, fmt.Errorf("invalid linkedin exchange code: %s", err.Error())
@ -542,7 +544,7 @@ func processLinkedInUserInfo(code string) (models.User, error) {
profilePicture := userRawData["profilePicture"].(map[string]interface{})["displayImage~"].(map[string]interface{})["elements"].([]interface{})[0].(map[string]interface{})["identifiers"].([]interface{})[0].(map[string]interface{})["identifier"].(string) profilePicture := userRawData["profilePicture"].(map[string]interface{})["displayImage~"].(map[string]interface{})["elements"].([]interface{})[0].(map[string]interface{})["identifiers"].([]interface{})[0].(map[string]interface{})["identifier"].(string)
emailAddress := emailRawData["elements"].([]interface{})[0].(map[string]interface{})["handle~"].(map[string]interface{})["emailAddress"].(string) emailAddress := emailRawData["elements"].([]interface{})[0].(map[string]interface{})["handle~"].(map[string]interface{})["emailAddress"].(string)
user = models.User{ user = &models.User{
GivenName: &firstName, GivenName: &firstName,
FamilyName: &lastName, FamilyName: &lastName,
Picture: &profilePicture, Picture: &profilePicture,
@ -552,9 +554,9 @@ func processLinkedInUserInfo(code string) (models.User, error) {
return user, nil return user, nil
} }
func processAppleUserInfo(code string) (models.User, error) { func processAppleUserInfo(ctx context.Context, code string) (*models.User, error) {
user := models.User{} var user *models.User
oauth2Token, err := oauth.OAuthProviders.AppleConfig.Exchange(context.TODO(), code) oauth2Token, err := oauth.OAuthProviders.AppleConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid apple exchange code: %s", err.Error()) return user, fmt.Errorf("invalid apple exchange code: %s", err.Error())
@ -605,9 +607,9 @@ func processAppleUserInfo(code string) (models.User, error) {
return user, err return user, err
} }
func processTwitterUserInfo(code, verifier string) (models.User, error) { func processTwitterUserInfo(ctx context.Context, code, verifier string) (*models.User, error) {
user := models.User{} var user *models.User
oauth2Token, err := oauth.OAuthProviders.TwitterConfig.Exchange(context.TODO(), code, oauth2.SetAuthURLParam("code_verifier", verifier)) oauth2Token, err := oauth.OAuthProviders.TwitterConfig.Exchange(ctx, code, oauth2.SetAuthURLParam("code_verifier", verifier))
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid twitter exchange code: %s", err.Error()) return user, fmt.Errorf("invalid twitter exchange code: %s", err.Error())
@ -662,7 +664,7 @@ func processTwitterUserInfo(code, verifier string) (models.User, error) {
nickname := userRawData["username"].(string) nickname := userRawData["username"].(string)
profilePicture := userRawData["profile_image_url"].(string) profilePicture := userRawData["profile_image_url"].(string)
user = models.User{ user = &models.User{
GivenName: &firstName, GivenName: &firstName,
FamilyName: &lastName, FamilyName: &lastName,
Picture: &profilePicture, Picture: &profilePicture,
@ -673,24 +675,24 @@ func processTwitterUserInfo(code, verifier string) (models.User, error) {
} }
// process microsoft user information // process microsoft user information
func processMicrosoftUserInfo(code string) (models.User, error) { func processMicrosoftUserInfo(ctx context.Context, code string) (*models.User, error) {
user := models.User{} var user *models.User
ctx := context.Background()
oauth2Token, err := oauth.OAuthProviders.MicrosoftConfig.Exchange(ctx, code) oauth2Token, err := oauth.OAuthProviders.MicrosoftConfig.Exchange(ctx, code)
if err != nil { if err != nil {
log.Debug("Failed to exchange code for token: ", err) log.Debug("Failed to exchange code for token: ", err)
return user, fmt.Errorf("invalid google exchange code: %s", err.Error()) return user, fmt.Errorf("invalid microsoft exchange code: %s", err.Error())
} }
// we need to skip issuer check because for common tenant it will return internal issuer which does not match
verifier := oauth.OIDCProviders.MicrosoftOIDC.Verifier(&oidc.Config{ClientID: oauth.OAuthProviders.MicrosoftConfig.ClientID}) verifier := oauth.OIDCProviders.MicrosoftOIDC.Verifier(&oidc.Config{
ClientID: oauth.OAuthProviders.MicrosoftConfig.ClientID,
SkipIssuerCheck: true,
})
// Extract the ID Token from OAuth2 token. // Extract the ID Token from OAuth2 token.
rawIDToken, ok := oauth2Token.Extra("id_token").(string) rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok { if !ok {
log.Debug("Failed to extract ID Token from OAuth2 token") log.Debug("Failed to extract ID Token from OAuth2 token")
return user, fmt.Errorf("unable to extract id_token") return user, fmt.Errorf("unable to extract id_token")
} }
// Parse and verify ID Token payload. // Parse and verify ID Token payload.
idToken, err := verifier.Verify(ctx, rawIDToken) idToken, err := verifier.Verify(ctx, rawIDToken)
if err != nil { if err != nil {

View File

@ -175,11 +175,12 @@ func VerifyEmailHandler() gin.HandlerFunc {
go func() { go func() {
if isSignUp { if isSignUp {
utils.RegisterEvent(c, constants.UserSignUpWebhookEvent, loginMethod, user) utils.RegisterEvent(c, constants.UserSignUpWebhookEvent, loginMethod, user)
// User is also logged in with signup
utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user)
} else { } else {
utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user) utils.RegisterEvent(c, constants.UserLoginWebhookEvent, loginMethod, user)
} }
db.Provider.AddSession(c, &models.Session{
db.Provider.AddSession(c, models.Session{
UserID: user.ID, UserID: user.ID,
UserAgent: utils.GetUserAgent(c.Request), UserAgent: utils.GetUserAgent(c.Request),
IP: utils.GetIP(c.Request), IP: utils.GetIP(c.Request),

View File

@ -33,6 +33,7 @@ func InitMemStore() error {
constants.EnvKeyDisableSignUp: false, constants.EnvKeyDisableSignUp: false,
constants.EnvKeyDisableStrongPassword: false, constants.EnvKeyDisableStrongPassword: false,
constants.EnvKeyIsEmailServiceEnabled: false, constants.EnvKeyIsEmailServiceEnabled: false,
constants.EnvKeyIsSMSServiceEnabled: false,
constants.EnvKeyEnforceMultiFactorAuthentication: false, constants.EnvKeyEnforceMultiFactorAuthentication: false,
constants.EnvKeyDisableMultiFactorAuthentication: false, constants.EnvKeyDisableMultiFactorAuthentication: false,
constants.EnvKeyAppCookieSecure: true, constants.EnvKeyAppCookieSecure: true,

View File

@ -9,6 +9,7 @@ import (
type provider struct { type provider struct {
mutex sync.Mutex mutex sync.Mutex
sessionStore *stores.SessionStore sessionStore *stores.SessionStore
mfasessionStore *stores.SessionStore
stateStore *stores.StateStore stateStore *stores.StateStore
envStore *stores.EnvStore envStore *stores.EnvStore
} }
@ -19,6 +20,7 @@ func NewInMemoryProvider() (*provider, error) {
mutex: sync.Mutex{}, mutex: sync.Mutex{},
envStore: stores.NewEnvStore(), envStore: stores.NewEnvStore(),
sessionStore: stores.NewSessionStore(), sessionStore: stores.NewSessionStore(),
mfasessionStore: stores.NewSessionStore(),
stateStore: stores.NewStateStore(), stateStore: stores.NewStateStore(),
}, nil }, nil
} }

View File

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

View File

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

View File

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

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