fix: bug with authorizer url
BIN
app/favicon_io/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
app/favicon_io/android-chrome-512x512.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
app/favicon_io/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
app/favicon_io/favicon-16x16.png
Normal file
After Width: | Height: | Size: 528 B |
BIN
app/favicon_io/favicon-32x32.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
app/favicon_io/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
dashboard/favicon_io/android-chrome-192x192.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
dashboard/favicon_io/android-chrome-512x512.png
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
dashboard/favicon_io/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
dashboard/favicon_io/favicon-16x16.png
Normal file
After Width: | Height: | Size: 528 B |
BIN
dashboard/favicon_io/favicon-32x32.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
dashboard/favicon_io/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
|
@ -64,6 +64,7 @@ export const UserDetailsQuery = `
|
||||||
birthdate
|
birthdate
|
||||||
phone_number
|
phone_number
|
||||||
picture
|
picture
|
||||||
|
signup_methods
|
||||||
roles
|
roles
|
||||||
created_at
|
created_at
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ interface userDataTypes {
|
||||||
birthdate: string;
|
birthdate: string;
|
||||||
phone_number: string;
|
phone_number: string;
|
||||||
picture: string;
|
picture: string;
|
||||||
|
signup_methods: string;
|
||||||
roles: [string];
|
roles: [string];
|
||||||
created_at: number;
|
created_at: number;
|
||||||
}
|
}
|
||||||
|
@ -167,6 +168,8 @@ export default function Users() {
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th>Email</Th>
|
<Th>Email</Th>
|
||||||
<Th>Created At</Th>
|
<Th>Created At</Th>
|
||||||
|
<Th>Signup Methods</Th>
|
||||||
|
<Th>Roles</Th>
|
||||||
<Th>Verified</Th>
|
<Th>Verified</Th>
|
||||||
<Th>Actions</Th>
|
<Th>Actions</Th>
|
||||||
</Tr>
|
</Tr>
|
||||||
|
@ -177,7 +180,11 @@ export default function Users() {
|
||||||
return (
|
return (
|
||||||
<Tr key={user.id} style={{ fontSize: 14 }}>
|
<Tr key={user.id} style={{ fontSize: 14 }}>
|
||||||
<Td>{user.email}</Td>
|
<Td>{user.email}</Td>
|
||||||
<Td>{dayjs(user.created_at).format('MMM DD, YYYY')}</Td>
|
<Td>
|
||||||
|
{dayjs(user.created_at * 1000).format('MMM DD, YYYY')}
|
||||||
|
</Td>
|
||||||
|
<Td>{user.signup_methods}</Td>
|
||||||
|
<Td>{user.roles.join(', ')}</Td>
|
||||||
<Td>
|
<Td>
|
||||||
<Tag
|
<Tag
|
||||||
size="sm"
|
size="sm"
|
||||||
|
|
|
@ -51,7 +51,10 @@ export const getObjectDiff = (obj1: any, obj2: any) => {
|
||||||
} else if (
|
} else if (
|
||||||
_.isEqual(obj1[key], obj2[key]) ||
|
_.isEqual(obj1[key], obj2[key]) ||
|
||||||
(obj1[key] === null && obj2[key] === '') ||
|
(obj1[key] === null && obj2[key] === '') ||
|
||||||
(obj1[key] === [] && obj2[key] === null)
|
(obj1[key] &&
|
||||||
|
Array.isArray(obj1[key]) &&
|
||||||
|
obj1[key].length === 0 &&
|
||||||
|
obj2[key] === null)
|
||||||
) {
|
) {
|
||||||
const resultKeyIndex = result.indexOf(key);
|
const resultKeyIndex = result.indexOf(key);
|
||||||
result.splice(resultKeyIndex, 1);
|
result.splice(resultKeyIndex, 1);
|
||||||
|
|
|
@ -16,6 +16,7 @@ const (
|
||||||
// EnvKeyVersion key for build arg version
|
// EnvKeyVersion key for build arg version
|
||||||
EnvKeyVersion = "VERSION"
|
EnvKeyVersion = "VERSION"
|
||||||
// EnvKeyAuthorizerURL key for env variable AUTHORIZER_URL
|
// EnvKeyAuthorizerURL key for env variable AUTHORIZER_URL
|
||||||
|
// TODO: remove support AUTHORIZER_URL env
|
||||||
EnvKeyAuthorizerURL = "AUTHORIZER_URL"
|
EnvKeyAuthorizerURL = "AUTHORIZER_URL"
|
||||||
// EnvKeyPort key for env variable PORT
|
// EnvKeyPort key for env variable PORT
|
||||||
EnvKeyPort = "PORT"
|
EnvKeyPort = "PORT"
|
||||||
|
|
|
@ -13,7 +13,8 @@ import (
|
||||||
func SetAdminCookie(gc *gin.Context, token string) {
|
func SetAdminCookie(gc *gin.Context, token string) {
|
||||||
secure := true
|
secure := true
|
||||||
httpOnly := true
|
httpOnly := true
|
||||||
host, _ := utils.GetHostParts(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL))
|
hostname := utils.GetHost(gc)
|
||||||
|
host, _ := utils.GetHostParts(hostname)
|
||||||
|
|
||||||
gc.SetCookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), token, 3600, "/", host, secure, httpOnly)
|
gc.SetCookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), token, 3600, "/", host, secure, httpOnly)
|
||||||
}
|
}
|
||||||
|
@ -38,7 +39,8 @@ func GetAdminCookie(gc *gin.Context) (string, error) {
|
||||||
func DeleteAdminCookie(gc *gin.Context) {
|
func DeleteAdminCookie(gc *gin.Context) {
|
||||||
secure := true
|
secure := true
|
||||||
httpOnly := true
|
httpOnly := true
|
||||||
host, _ := utils.GetHostParts(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL))
|
hostname := utils.GetHost(gc)
|
||||||
|
host, _ := utils.GetHostParts(hostname)
|
||||||
|
|
||||||
gc.SetCookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), "", -1, "/", host, secure, httpOnly)
|
gc.SetCookie(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminCookieName), "", -1, "/", host, secure, httpOnly)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,9 @@ import (
|
||||||
func SetCookie(gc *gin.Context, accessToken, refreshToken, fingerprintHash string) {
|
func SetCookie(gc *gin.Context, accessToken, refreshToken, fingerprintHash string) {
|
||||||
secure := true
|
secure := true
|
||||||
httpOnly := true
|
httpOnly := true
|
||||||
host, _ := utils.GetHostParts(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL))
|
hostname := utils.GetHost(gc)
|
||||||
domain := utils.GetDomainName(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL))
|
host, _ := utils.GetHostParts(hostname)
|
||||||
|
domain := utils.GetDomainName(hostname)
|
||||||
if domain != "localhost" {
|
if domain != "localhost" {
|
||||||
domain = "." + domain
|
domain = "." + domain
|
||||||
}
|
}
|
||||||
|
@ -86,9 +87,9 @@ func GetFingerPrintCookie(gc *gin.Context) (string, error) {
|
||||||
func DeleteCookie(gc *gin.Context) {
|
func DeleteCookie(gc *gin.Context) {
|
||||||
secure := true
|
secure := true
|
||||||
httpOnly := true
|
httpOnly := true
|
||||||
|
hostname := utils.GetHost(gc)
|
||||||
host, _ := utils.GetHostParts(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL))
|
host, _ := utils.GetHostParts(hostname)
|
||||||
domain := utils.GetDomainName(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL))
|
domain := utils.GetDomainName(hostname)
|
||||||
if domain != "localhost" {
|
if domain != "localhost" {
|
||||||
domain = "." + domain
|
domain = "." + domain
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,6 @@ type Env struct {
|
||||||
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id"`
|
ID string `gorm:"primaryKey;type:char(36)" json:"_id" bson:"_id"`
|
||||||
EnvData string `gorm:"type:text" json:"env" bson:"env"`
|
EnvData string `gorm:"type:text" json:"env" bson:"env"`
|
||||||
Hash string `gorm:"type:text" json:"hash" bson:"hash"`
|
Hash string `gorm:"type:text" json:"hash" bson:"hash"`
|
||||||
UpdatedAt int64 `gorm:"autoUpdateTime" json:"updated_at" bson:"updated_at"`
|
UpdatedAt int64 `json:"updated_at" bson:"updated_at"`
|
||||||
CreatedAt int64 `gorm:"autoCreateTime" json:"created_at" bson:"created_at"`
|
CreatedAt int64 `json:"created_at" bson:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,6 @@ type Session struct {
|
||||||
User User `json:"-" bson:"-"`
|
User User `json:"-" bson:"-"`
|
||||||
UserAgent string `json:"user_agent" bson:"user_agent"`
|
UserAgent string `json:"user_agent" bson:"user_agent"`
|
||||||
IP string `json:"ip" bson:"ip"`
|
IP string `json:"ip" bson:"ip"`
|
||||||
CreatedAt int64 `gorm:"autoCreateTime" json:"created_at" bson:"created_at"`
|
CreatedAt int64 `json:"created_at" bson:"created_at"`
|
||||||
UpdatedAt int64 `gorm:"autoUpdateTime" json:"updated_at" bson:"updated_at"`
|
UpdatedAt int64 `json:"updated_at" bson:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,8 @@ type User struct {
|
||||||
PhoneNumberVerifiedAt *int64 `json:"phone_number_verified_at" bson:"phone_number_verified_at"`
|
PhoneNumberVerifiedAt *int64 `json:"phone_number_verified_at" bson:"phone_number_verified_at"`
|
||||||
Picture *string `gorm:"type:text" json:"picture" bson:"picture"`
|
Picture *string `gorm:"type:text" json:"picture" bson:"picture"`
|
||||||
Roles string `json:"roles" bson:"roles"`
|
Roles string `json:"roles" bson:"roles"`
|
||||||
UpdatedAt int64 `gorm:"autoUpdateTime" json:"updated_at" bson:"updated_at"`
|
UpdatedAt int64 `json:"updated_at" bson:"updated_at"`
|
||||||
CreatedAt int64 `gorm:"autoCreateTime" json:"created_at" bson:"created_at"`
|
CreatedAt int64 `json:"created_at" bson:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (user *User) AsAPIUser() *model.User {
|
func (user *User) AsAPIUser() *model.User {
|
||||||
|
|
|
@ -9,8 +9,8 @@ type VerificationRequest struct {
|
||||||
Token string `gorm:"type:text" json:"token" bson:"token"`
|
Token string `gorm:"type:text" json:"token" bson:"token"`
|
||||||
Identifier string `gorm:"uniqueIndex:idx_email_identifier" json:"identifier" bson:"identifier"`
|
Identifier string `gorm:"uniqueIndex:idx_email_identifier" json:"identifier" bson:"identifier"`
|
||||||
ExpiresAt int64 `json:"expires_at" bson:"expires_at"`
|
ExpiresAt int64 `json:"expires_at" bson:"expires_at"`
|
||||||
CreatedAt int64 `gorm:"autoCreateTime" json:"created_at" bson:"created_at"`
|
CreatedAt int64 `json:"created_at" bson:"created_at"`
|
||||||
UpdatedAt int64 `gorm:"autoUpdateTime" json:"updated_at" bson:"updated_at"`
|
UpdatedAt int64 `json:"updated_at" bson:"updated_at"`
|
||||||
Email string `gorm:"uniqueIndex:idx_email_identifier" json:"email" bson:"email"`
|
Email string `gorm:"uniqueIndex:idx_email_identifier" json:"email" bson:"email"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,10 @@ func (p *provider) AddEnv(env models.Env) (models.Env, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
env.Key = env.ID
|
env.Key = env.ID
|
||||||
result := p.db.Create(&env)
|
env.CreatedAt = time.Now().Unix()
|
||||||
|
env.UpdatedAt = time.Now().Unix()
|
||||||
|
|
||||||
|
result := p.db.Create(&env)
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
log.Println("error adding config:", result.Error)
|
log.Println("error adding config:", result.Error)
|
||||||
return env, result.Error
|
return env, result.Error
|
||||||
|
|
|
@ -2,6 +2,7 @@ package sql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
@ -15,6 +16,8 @@ func (p *provider) AddSession(session models.Session) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
session.Key = session.ID
|
session.Key = session.ID
|
||||||
|
session.CreatedAt = time.Now().Unix()
|
||||||
|
session.UpdatedAt = time.Now().Unix()
|
||||||
res := p.db.Clauses(
|
res := p.db.Clauses(
|
||||||
clause.OnConflict{
|
clause.OnConflict{
|
||||||
DoNothing: true,
|
DoNothing: true,
|
||||||
|
|
|
@ -23,6 +23,8 @@ func (p *provider) AddUser(user models.User) (models.User, error) {
|
||||||
user.Roles = strings.Join(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",")
|
user.Roles = strings.Join(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user.CreatedAt = time.Now().Unix()
|
||||||
|
user.UpdatedAt = time.Now().Unix()
|
||||||
user.Key = user.ID
|
user.Key = user.ID
|
||||||
result := p.db.Clauses(
|
result := p.db.Clauses(
|
||||||
clause.OnConflict{
|
clause.OnConflict{
|
||||||
|
|
|
@ -2,6 +2,7 @@ package sql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/db/models"
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
|
@ -16,6 +17,8 @@ func (p *provider) AddVerificationRequest(verificationRequest models.Verificatio
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationRequest.Key = verificationRequest.ID
|
verificationRequest.Key = verificationRequest.ID
|
||||||
|
verificationRequest.CreatedAt = time.Now().Unix()
|
||||||
|
verificationRequest.UpdatedAt = time.Now().Unix()
|
||||||
result := p.db.Clauses(clause.OnConflict{
|
result := p.db.Clauses(clause.OnConflict{
|
||||||
Columns: []clause.Column{{Name: "email"}, {Name: "identifier"}},
|
Columns: []clause.Column{{Name: "email"}, {Name: "identifier"}},
|
||||||
DoUpdates: clause.AssignmentColumns([]string{"token", "expires_at"}),
|
DoUpdates: clause.AssignmentColumns([]string{"token", "expires_at"}),
|
||||||
|
|
|
@ -6,10 +6,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// SendForgotPasswordMail to send forgot password email
|
// SendForgotPasswordMail to send forgot password email
|
||||||
func SendForgotPasswordMail(toEmail, token, host string) error {
|
func SendForgotPasswordMail(toEmail, token, hostname string) error {
|
||||||
resetPasswordUrl := envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyResetPasswordURL)
|
resetPasswordUrl := envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyResetPasswordURL)
|
||||||
if resetPasswordUrl == "" {
|
if resetPasswordUrl == "" {
|
||||||
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyResetPasswordURL, envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)+"/app/reset-password")
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyResetPasswordURL, hostname+"/app/reset-password")
|
||||||
}
|
}
|
||||||
|
|
||||||
// The receiver needs to be in slice as the receive supports multiple receiver
|
// The receiver needs to be in slice as the receive supports multiple receiver
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// SendVerificationMail to send verification email
|
// SendVerificationMail to send verification email
|
||||||
func SendVerificationMail(toEmail, token string) error {
|
func SendVerificationMail(toEmail, token, hostname string) error {
|
||||||
// The receiver needs to be in slice as the receive supports multiple receiver
|
// The receiver needs to be in slice as the receive supports multiple receiver
|
||||||
Receiver := []string{toEmail}
|
Receiver := []string{toEmail}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ func SendVerificationMail(toEmail, token string) error {
|
||||||
data := make(map[string]interface{}, 3)
|
data := make(map[string]interface{}, 3)
|
||||||
data["org_logo"] = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo)
|
data["org_logo"] = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo)
|
||||||
data["org_name"] = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName)
|
data["org_name"] = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName)
|
||||||
data["verification_url"] = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/verify_email?token=" + token
|
data["verification_url"] = hostname + "/verify_email?token=" + token
|
||||||
message = addEmailTemplate(message, data, "verify_email.tmpl")
|
message = addEmailTemplate(message, data, "verify_email.tmpl")
|
||||||
// bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message)
|
// bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message)
|
||||||
|
|
||||||
|
|
5
server/env/env.go
vendored
|
@ -31,8 +31,6 @@ func InitEnv() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set authorizer url to empty string so that fresh url is obtained with every server start
|
|
||||||
envData.StringEnv[constants.EnvKeyAuthorizerURL] = ""
|
|
||||||
if envData.StringEnv[constants.EnvKeyAppURL] == "" {
|
if envData.StringEnv[constants.EnvKeyAppURL] == "" {
|
||||||
envData.StringEnv[constants.EnvKeyAppURL] = os.Getenv(constants.EnvKeyAppURL)
|
envData.StringEnv[constants.EnvKeyAppURL] = os.Getenv(constants.EnvKeyAppURL)
|
||||||
}
|
}
|
||||||
|
@ -246,12 +244,11 @@ func InitEnv() {
|
||||||
trimVal := strings.TrimSpace(val)
|
trimVal := strings.TrimSpace(val)
|
||||||
if trimVal != "" {
|
if trimVal != "" {
|
||||||
roles = append(roles, trimVal)
|
roles = append(roles, trimVal)
|
||||||
}
|
|
||||||
|
|
||||||
if utils.StringSliceContains(defaultRoleSplit, trimVal) {
|
if utils.StringSliceContains(defaultRoleSplit, trimVal) {
|
||||||
defaultRoles = append(defaultRoles, trimVal)
|
defaultRoles = append(defaultRoles, trimVal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(roles) > 0 && len(defaultRoles) == 0 && len(defaultRolesEnv) > 0 {
|
if len(roles) > 0 && len(defaultRoles) == 0 && len(defaultRolesEnv) > 0 {
|
||||||
panic(`Invalid DEFAULT_ROLE environment variable. It can be one from give ROLES environment variable value`)
|
panic(`Invalid DEFAULT_ROLE environment variable. It can be one from give ROLES environment variable value`)
|
||||||
|
|
|
@ -6,7 +6,6 @@ require (
|
||||||
github.com/99designs/gqlgen v0.14.0
|
github.com/99designs/gqlgen v0.14.0
|
||||||
github.com/arangodb/go-driver v1.2.1
|
github.com/arangodb/go-driver v1.2.1
|
||||||
github.com/coreos/go-oidc/v3 v3.1.0
|
github.com/coreos/go-oidc/v3 v3.1.0
|
||||||
github.com/gin-contrib/location v0.0.2
|
|
||||||
github.com/gin-gonic/gin v1.7.2
|
github.com/gin-gonic/gin v1.7.2
|
||||||
github.com/go-playground/validator/v10 v10.8.0 // indirect
|
github.com/go-playground/validator/v10 v10.8.0 // indirect
|
||||||
github.com/go-redis/redis/v8 v8.11.0
|
github.com/go-redis/redis/v8 v8.11.0
|
||||||
|
|
|
@ -82,11 +82,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
github.com/gin-contrib/location v0.0.2 h1:QZKh1+K/LLR4KG/61eIO3b7MLuKi8tytQhV6texLgP4=
|
|
||||||
github.com/gin-contrib/location v0.0.2/go.mod h1:NGoidiRlf0BlA/VKSVp+g3cuSMeTmip/63PhEjRhUAc=
|
|
||||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
|
||||||
github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA=
|
github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA=
|
||||||
github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
|
@ -100,7 +97,6 @@ github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8c
|
||||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
|
||||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||||
github.com/go-playground/validator/v10 v10.8.0 h1:1kAa0fCrnpv+QYdkdcRzrRM7AyYs5o8+jZdJCz9xj6k=
|
github.com/go-playground/validator/v10 v10.8.0 h1:1kAa0fCrnpv+QYdkdcRzrRM7AyYs5o8+jZdJCz9xj6k=
|
||||||
github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
|
github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
|
||||||
|
|
|
@ -54,7 +54,6 @@ type ComplexityRoot struct {
|
||||||
AdminSecret func(childComplexity int) int
|
AdminSecret func(childComplexity int) int
|
||||||
AllowedOrigins func(childComplexity int) int
|
AllowedOrigins func(childComplexity int) int
|
||||||
AppURL func(childComplexity int) int
|
AppURL func(childComplexity int) int
|
||||||
AuthorizerURL func(childComplexity int) int
|
|
||||||
CookieName func(childComplexity int) int
|
CookieName func(childComplexity int) int
|
||||||
CustomAccessTokenScript func(childComplexity int) int
|
CustomAccessTokenScript func(childComplexity int) int
|
||||||
DatabaseName func(childComplexity int) int
|
DatabaseName func(childComplexity int) int
|
||||||
|
@ -280,13 +279,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Env.AppURL(childComplexity), true
|
return e.complexity.Env.AppURL(childComplexity), true
|
||||||
|
|
||||||
case "Env.AUTHORIZER_URL":
|
|
||||||
if e.complexity.Env.AuthorizerURL == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
return e.complexity.Env.AuthorizerURL(childComplexity), true
|
|
||||||
|
|
||||||
case "Env.COOKIE_NAME":
|
case "Env.COOKIE_NAME":
|
||||||
if e.complexity.Env.CookieName == nil {
|
if e.complexity.Env.CookieName == nil {
|
||||||
break
|
break
|
||||||
|
@ -1215,7 +1207,6 @@ type Env {
|
||||||
JWT_TYPE: String
|
JWT_TYPE: String
|
||||||
JWT_SECRET: String
|
JWT_SECRET: String
|
||||||
ALLOWED_ORIGINS: [String!]
|
ALLOWED_ORIGINS: [String!]
|
||||||
AUTHORIZER_URL: String
|
|
||||||
APP_URL: String
|
APP_URL: String
|
||||||
REDIS_URL: String
|
REDIS_URL: String
|
||||||
COOKIE_NAME: String
|
COOKIE_NAME: String
|
||||||
|
@ -1250,7 +1241,6 @@ input UpdateEnvInput {
|
||||||
JWT_TYPE: String
|
JWT_TYPE: String
|
||||||
JWT_SECRET: String
|
JWT_SECRET: String
|
||||||
ALLOWED_ORIGINS: [String!]
|
ALLOWED_ORIGINS: [String!]
|
||||||
AUTHORIZER_URL: String
|
|
||||||
APP_URL: String
|
APP_URL: String
|
||||||
REDIS_URL: String
|
REDIS_URL: String
|
||||||
COOKIE_NAME: String
|
COOKIE_NAME: String
|
||||||
|
@ -2271,38 +2261,6 @@ func (ec *executionContext) _Env_ALLOWED_ORIGINS(ctx context.Context, field grap
|
||||||
return ec.marshalOString2ᚕstringᚄ(ctx, field.Selections, res)
|
return ec.marshalOString2ᚕstringᚄ(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Env_AUTHORIZER_URL(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
ec.Error(ctx, ec.Recover(ctx, r))
|
|
||||||
ret = graphql.Null
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
fc := &graphql.FieldContext{
|
|
||||||
Object: "Env",
|
|
||||||
Field: field,
|
|
||||||
Args: nil,
|
|
||||||
IsMethod: false,
|
|
||||||
IsResolver: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = graphql.WithFieldContext(ctx, fc)
|
|
||||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
|
||||||
ctx = rctx // use context from middleware stack in children
|
|
||||||
return obj.AuthorizerURL, nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ec.Error(ctx, err)
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
if resTmp == nil {
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
res := resTmp.(*string)
|
|
||||||
fc.Result = res
|
|
||||||
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) _Env_APP_URL(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Env_APP_URL(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
|
@ -7094,14 +7052,6 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return it, err
|
return it, err
|
||||||
}
|
}
|
||||||
case "AUTHORIZER_URL":
|
|
||||||
var err error
|
|
||||||
|
|
||||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("AUTHORIZER_URL"))
|
|
||||||
it.AuthorizerURL, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
|
||||||
if err != nil {
|
|
||||||
return it, err
|
|
||||||
}
|
|
||||||
case "APP_URL":
|
case "APP_URL":
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -7591,8 +7541,6 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, obj
|
||||||
out.Values[i] = ec._Env_JWT_SECRET(ctx, field, obj)
|
out.Values[i] = ec._Env_JWT_SECRET(ctx, field, obj)
|
||||||
case "ALLOWED_ORIGINS":
|
case "ALLOWED_ORIGINS":
|
||||||
out.Values[i] = ec._Env_ALLOWED_ORIGINS(ctx, field, obj)
|
out.Values[i] = ec._Env_ALLOWED_ORIGINS(ctx, field, obj)
|
||||||
case "AUTHORIZER_URL":
|
|
||||||
out.Values[i] = ec._Env_AUTHORIZER_URL(ctx, field, obj)
|
|
||||||
case "APP_URL":
|
case "APP_URL":
|
||||||
out.Values[i] = ec._Env_APP_URL(ctx, field, obj)
|
out.Values[i] = ec._Env_APP_URL(ctx, field, obj)
|
||||||
case "REDIS_URL":
|
case "REDIS_URL":
|
||||||
|
|
|
@ -35,7 +35,6 @@ type Env struct {
|
||||||
JwtType *string `json:"JWT_TYPE"`
|
JwtType *string `json:"JWT_TYPE"`
|
||||||
JwtSecret *string `json:"JWT_SECRET"`
|
JwtSecret *string `json:"JWT_SECRET"`
|
||||||
AllowedOrigins []string `json:"ALLOWED_ORIGINS"`
|
AllowedOrigins []string `json:"ALLOWED_ORIGINS"`
|
||||||
AuthorizerURL *string `json:"AUTHORIZER_URL"`
|
|
||||||
AppURL *string `json:"APP_URL"`
|
AppURL *string `json:"APP_URL"`
|
||||||
RedisURL *string `json:"REDIS_URL"`
|
RedisURL *string `json:"REDIS_URL"`
|
||||||
CookieName *string `json:"COOKIE_NAME"`
|
CookieName *string `json:"COOKIE_NAME"`
|
||||||
|
@ -155,7 +154,6 @@ type UpdateEnvInput struct {
|
||||||
JwtType *string `json:"JWT_TYPE"`
|
JwtType *string `json:"JWT_TYPE"`
|
||||||
JwtSecret *string `json:"JWT_SECRET"`
|
JwtSecret *string `json:"JWT_SECRET"`
|
||||||
AllowedOrigins []string `json:"ALLOWED_ORIGINS"`
|
AllowedOrigins []string `json:"ALLOWED_ORIGINS"`
|
||||||
AuthorizerURL *string `json:"AUTHORIZER_URL"`
|
|
||||||
AppURL *string `json:"APP_URL"`
|
AppURL *string `json:"APP_URL"`
|
||||||
RedisURL *string `json:"REDIS_URL"`
|
RedisURL *string `json:"REDIS_URL"`
|
||||||
CookieName *string `json:"COOKIE_NAME"`
|
CookieName *string `json:"COOKIE_NAME"`
|
||||||
|
|
|
@ -98,7 +98,6 @@ type Env {
|
||||||
JWT_TYPE: String
|
JWT_TYPE: String
|
||||||
JWT_SECRET: String
|
JWT_SECRET: String
|
||||||
ALLOWED_ORIGINS: [String!]
|
ALLOWED_ORIGINS: [String!]
|
||||||
AUTHORIZER_URL: String
|
|
||||||
APP_URL: String
|
APP_URL: String
|
||||||
REDIS_URL: String
|
REDIS_URL: String
|
||||||
COOKIE_NAME: String
|
COOKIE_NAME: String
|
||||||
|
@ -133,7 +132,6 @@ input UpdateEnvInput {
|
||||||
JWT_TYPE: String
|
JWT_TYPE: String
|
||||||
JWT_SECRET: String
|
JWT_SECRET: String
|
||||||
ALLOWED_ORIGINS: [String!]
|
ALLOWED_ORIGINS: [String!]
|
||||||
AUTHORIZER_URL: String
|
|
||||||
APP_URL: String
|
APP_URL: String
|
||||||
REDIS_URL: String
|
REDIS_URL: String
|
||||||
COOKIE_NAME: String
|
COOKIE_NAME: String
|
||||||
|
|
|
@ -22,6 +22,7 @@ type State struct {
|
||||||
// AppHandler is the handler for the /app route
|
// AppHandler is the handler for the /app route
|
||||||
func AppHandler() gin.HandlerFunc {
|
func AppHandler() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
|
hostname := utils.GetHost(c)
|
||||||
if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage) {
|
if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableLoginPage) {
|
||||||
c.JSON(400, gin.H{"error": "login page is not enabled"})
|
c.JSON(400, gin.H{"error": "login page is not enabled"})
|
||||||
return
|
return
|
||||||
|
@ -32,7 +33,8 @@ func AppHandler() gin.HandlerFunc {
|
||||||
var stateObj State
|
var stateObj State
|
||||||
|
|
||||||
if state == "" {
|
if state == "" {
|
||||||
stateObj.AuthorizerURL = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL)
|
|
||||||
|
stateObj.AuthorizerURL = hostname
|
||||||
stateObj.RedirectURL = stateObj.AuthorizerURL + "/app"
|
stateObj.RedirectURL = stateObj.AuthorizerURL + "/app"
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -62,7 +64,7 @@ func AppHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate host and domain of authorizer url
|
// validate host and domain of authorizer url
|
||||||
if strings.TrimSuffix(stateObj.AuthorizerURL, "/") != envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) {
|
if strings.TrimSuffix(stateObj.AuthorizerURL, "/") != hostname {
|
||||||
c.JSON(400, gin.H{"error": "invalid host url"})
|
c.JSON(400, gin.H{"error": "invalid host url"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,11 @@ func OAuthCallbackHandler() gin.HandlerFunc {
|
||||||
user.SignupMethods = signupMethod
|
user.SignupMethods = signupMethod
|
||||||
user.Password = existingUser.Password
|
user.Password = existingUser.Password
|
||||||
|
|
||||||
|
if user.EmailVerifiedAt == nil {
|
||||||
|
now := time.Now().Unix()
|
||||||
|
user.EmailVerifiedAt = &now
|
||||||
|
}
|
||||||
|
|
||||||
// There multiple scenarios with roles here in social login
|
// There multiple scenarios with roles here in social login
|
||||||
// 1. user has access to protected roles + roles and trying to login
|
// 1. user has access to protected roles + roles and trying to login
|
||||||
// 2. user has not signed up for one of the available role but trying to signup.
|
// 2. user has not signed up for one of the available role but trying to signup.
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
// OAuthLoginHandler set host in the oauth state that is useful for redirecting to oauth_callback
|
// OAuthLoginHandler set host in the oauth state that is useful for redirecting to oauth_callback
|
||||||
func OAuthLoginHandler() gin.HandlerFunc {
|
func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
// TODO validate redirect URL
|
hostname := utils.GetHost(c)
|
||||||
redirectURL := c.Query("redirectURL")
|
redirectURL := c.Query("redirectURL")
|
||||||
roles := c.Query("roles")
|
roles := c.Query("roles")
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
}
|
}
|
||||||
sessionstore.SetSocailLoginState(oauthStateString, constants.SignupMethodGoogle)
|
sessionstore.SetSocailLoginState(oauthStateString, constants.SignupMethodGoogle)
|
||||||
// during the init of OAuthProvider authorizer url might be empty
|
// during the init of OAuthProvider authorizer url might be empty
|
||||||
oauth.OAuthProviders.GoogleConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/google"
|
oauth.OAuthProviders.GoogleConfig.RedirectURL = hostname + "/oauth_callback/google"
|
||||||
url := oauth.OAuthProviders.GoogleConfig.AuthCodeURL(oauthStateString)
|
url := oauth.OAuthProviders.GoogleConfig.AuthCodeURL(oauthStateString)
|
||||||
c.Redirect(http.StatusTemporaryRedirect, url)
|
c.Redirect(http.StatusTemporaryRedirect, url)
|
||||||
case constants.SignupMethodGithub:
|
case constants.SignupMethodGithub:
|
||||||
|
@ -65,7 +65,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
sessionstore.SetSocailLoginState(oauthStateString, constants.SignupMethodGithub)
|
sessionstore.SetSocailLoginState(oauthStateString, constants.SignupMethodGithub)
|
||||||
oauth.OAuthProviders.GithubConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/github"
|
oauth.OAuthProviders.GithubConfig.RedirectURL = hostname + "/oauth_callback/github"
|
||||||
url := oauth.OAuthProviders.GithubConfig.AuthCodeURL(oauthStateString)
|
url := oauth.OAuthProviders.GithubConfig.AuthCodeURL(oauthStateString)
|
||||||
c.Redirect(http.StatusTemporaryRedirect, url)
|
c.Redirect(http.StatusTemporaryRedirect, url)
|
||||||
case constants.SignupMethodFacebook:
|
case constants.SignupMethodFacebook:
|
||||||
|
@ -74,7 +74,7 @@ func OAuthLoginHandler() gin.HandlerFunc {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
sessionstore.SetSocailLoginState(oauthStateString, constants.SignupMethodFacebook)
|
sessionstore.SetSocailLoginState(oauthStateString, constants.SignupMethodFacebook)
|
||||||
oauth.OAuthProviders.FacebookConfig.RedirectURL = envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/facebook"
|
oauth.OAuthProviders.FacebookConfig.RedirectURL = hostname + "/oauth_callback/facebook"
|
||||||
url := oauth.OAuthProviders.FacebookConfig.AuthCodeURL(oauthStateString)
|
url := oauth.OAuthProviders.FacebookConfig.AuthCodeURL(oauthStateString)
|
||||||
c.Redirect(http.StatusTemporaryRedirect, url)
|
c.Redirect(http.StatusTemporaryRedirect, url)
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -2,22 +2,13 @@ package middlewares
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
|
||||||
"github.com/gin-contrib/location"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GinContextToContextMiddleware is a middleware to add gin context in context
|
// GinContextToContextMiddleware is a middleware to add gin context in context
|
||||||
func GinContextToContextMiddleware() gin.HandlerFunc {
|
func GinContextToContextMiddleware() gin.HandlerFunc {
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
if envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) == "" {
|
|
||||||
url := location.Get(c)
|
|
||||||
log.Println("=> setting authorizer url to: " + url.Scheme + "://" + c.Request.Host)
|
|
||||||
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyAuthorizerURL, url.Scheme+"://"+c.Request.Host)
|
|
||||||
}
|
|
||||||
ctx := context.WithValue(c.Request.Context(), "GinContextKey", c)
|
ctx := context.WithValue(c.Request.Context(), "GinContextKey", c)
|
||||||
c.Request = c.Request.WithContext(ctx)
|
c.Request = c.Request.WithContext(ctx)
|
||||||
c.Next()
|
c.Next()
|
||||||
|
|
|
@ -43,7 +43,7 @@ func InitOAuth() {
|
||||||
OAuthProviders.GoogleConfig = &oauth2.Config{
|
OAuthProviders.GoogleConfig = &oauth2.Config{
|
||||||
ClientID: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID),
|
ClientID: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientID),
|
||||||
ClientSecret: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret),
|
ClientSecret: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGoogleClientSecret),
|
||||||
RedirectURL: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/google",
|
RedirectURL: "/oauth_callback/google",
|
||||||
Endpoint: OIDCProviders.GoogleOIDC.Endpoint(),
|
Endpoint: OIDCProviders.GoogleOIDC.Endpoint(),
|
||||||
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
|
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ func InitOAuth() {
|
||||||
OAuthProviders.GithubConfig = &oauth2.Config{
|
OAuthProviders.GithubConfig = &oauth2.Config{
|
||||||
ClientID: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID),
|
ClientID: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientID),
|
||||||
ClientSecret: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret),
|
ClientSecret: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyGithubClientSecret),
|
||||||
RedirectURL: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/github",
|
RedirectURL: "/oauth_callback/github",
|
||||||
Endpoint: githubOAuth2.Endpoint,
|
Endpoint: githubOAuth2.Endpoint,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ func InitOAuth() {
|
||||||
OAuthProviders.FacebookConfig = &oauth2.Config{
|
OAuthProviders.FacebookConfig = &oauth2.Config{
|
||||||
ClientID: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID),
|
ClientID: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientID),
|
||||||
ClientSecret: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientSecret),
|
ClientSecret: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyFacebookClientSecret),
|
||||||
RedirectURL: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL) + "/oauth_callback/facebook",
|
RedirectURL: "/oauth_callback/facebook",
|
||||||
Endpoint: facebookOAuth2.Endpoint,
|
Endpoint: facebookOAuth2.Endpoint,
|
||||||
Scopes: []string{"public_profile", "email"},
|
Scopes: []string{"public_profile", "email"},
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,6 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
|
||||||
jwtSecret := store.StringEnv[constants.EnvKeyJwtSecret]
|
jwtSecret := store.StringEnv[constants.EnvKeyJwtSecret]
|
||||||
jwtRoleClaim := store.StringEnv[constants.EnvKeyJwtRoleClaim]
|
jwtRoleClaim := store.StringEnv[constants.EnvKeyJwtRoleClaim]
|
||||||
allowedOrigins := store.SliceEnv[constants.EnvKeyAllowedOrigins]
|
allowedOrigins := store.SliceEnv[constants.EnvKeyAllowedOrigins]
|
||||||
authorizerURL := store.StringEnv[constants.EnvKeyAuthorizerURL]
|
|
||||||
appURL := store.StringEnv[constants.EnvKeyAppURL]
|
appURL := store.StringEnv[constants.EnvKeyAppURL]
|
||||||
redisURL := store.StringEnv[constants.EnvKeyRedisURL]
|
redisURL := store.StringEnv[constants.EnvKeyRedisURL]
|
||||||
cookieName := store.StringEnv[constants.EnvKeyCookieName]
|
cookieName := store.StringEnv[constants.EnvKeyCookieName]
|
||||||
|
@ -77,7 +76,6 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
|
||||||
JwtSecret: &jwtSecret,
|
JwtSecret: &jwtSecret,
|
||||||
JwtRoleClaim: &jwtRoleClaim,
|
JwtRoleClaim: &jwtRoleClaim,
|
||||||
AllowedOrigins: allowedOrigins,
|
AllowedOrigins: allowedOrigins,
|
||||||
AuthorizerURL: &authorizerURL,
|
|
||||||
AppURL: &appURL,
|
AppURL: &appURL,
|
||||||
RedisURL: &redisURL,
|
RedisURL: &redisURL,
|
||||||
CookieName: &cookieName,
|
CookieName: &cookieName,
|
||||||
|
|
|
@ -27,7 +27,6 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
|
||||||
if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
|
if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) {
|
||||||
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
return res, fmt.Errorf(`basic authentication is disabled for this instance`)
|
||||||
}
|
}
|
||||||
host := gc.Request.Host
|
|
||||||
params.Email = strings.ToLower(params.Email)
|
params.Email = strings.ToLower(params.Email)
|
||||||
|
|
||||||
if !utils.IsValidEmail(params.Email) {
|
if !utils.IsValidEmail(params.Email) {
|
||||||
|
@ -39,7 +38,8 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
|
||||||
return res, fmt.Errorf(`user with this email not found`)
|
return res, fmt.Errorf(`user with this email not found`)
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationToken, err := token.CreateVerificationToken(params.Email, constants.VerificationTypeForgotPassword)
|
hostname := utils.GetHost(gc)
|
||||||
|
verificationToken, err := token.CreateVerificationToken(params.Email, constants.VerificationTypeForgotPassword, hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Println(`error generating token`, err)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
email.SendForgotPasswordMail(params.Email, verificationToken, host)
|
email.SendForgotPasswordMail(params.Email, verificationToken, hostname)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
res = &model.Response{
|
res = &model.Response{
|
||||||
|
|
|
@ -20,6 +20,10 @@ import (
|
||||||
// MagicLinkLoginResolver is a resolver for magic link login mutation
|
// MagicLinkLoginResolver is a resolver for magic link login mutation
|
||||||
func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) {
|
func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInput) (*model.Response, error) {
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) {
|
if envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) {
|
||||||
return res, fmt.Errorf(`magic link login is disabled for this instance`)
|
return res, fmt.Errorf(`magic link login is disabled for this instance`)
|
||||||
|
@ -102,10 +106,11 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hostname := utils.GetHost(gc)
|
||||||
if !envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) {
|
if !envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) {
|
||||||
// insert verification request
|
// insert verification request
|
||||||
verificationType := constants.VerificationTypeMagicLinkLogin
|
verificationType := constants.VerificationTypeMagicLinkLogin
|
||||||
verificationToken, err := token.CreateVerificationToken(params.Email, verificationType)
|
verificationToken, err := token.CreateVerificationToken(params.Email, verificationType, hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Println(`error generating token`, err)
|
||||||
}
|
}
|
||||||
|
@ -118,7 +123,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
email.SendVerificationMail(params.Email, verificationToken)
|
email.SendVerificationMail(params.Email, verificationToken, hostname)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,10 @@ import (
|
||||||
// ResendVerifyEmailResolver is a resolver for resend verify email mutation
|
// ResendVerifyEmailResolver is a resolver for resend verify email mutation
|
||||||
func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error) {
|
func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEmailInput) (*model.Response, error) {
|
||||||
var res *model.Response
|
var res *model.Response
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
params.Email = strings.ToLower(params.Email)
|
params.Email = strings.ToLower(params.Email)
|
||||||
|
|
||||||
if !utils.IsValidEmail(params.Email) {
|
if !utils.IsValidEmail(params.Email) {
|
||||||
|
@ -39,7 +43,8 @@ func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEma
|
||||||
log.Println("error deleting verification request:", err)
|
log.Println("error deleting verification request:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
verificationToken, err := token.CreateVerificationToken(params.Email, params.Identifier)
|
hostname := utils.GetHost(gc)
|
||||||
|
verificationToken, err := token.CreateVerificationToken(params.Email, params.Identifier, hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Println(`error generating token`, err)
|
||||||
}
|
}
|
||||||
|
@ -52,7 +57,7 @@ func ResendVerifyEmailResolver(ctx context.Context, params model.ResendVerifyEma
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
email.SendVerificationMail(params.Email, verificationToken)
|
email.SendVerificationMail(params.Email, verificationToken, hostname)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
res = &model.Response{
|
res = &model.Response{
|
||||||
|
|
|
@ -119,10 +119,11 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||||
roles := strings.Split(user.Roles, ",")
|
roles := strings.Split(user.Roles, ",")
|
||||||
userToReturn := user.AsAPIUser()
|
userToReturn := user.AsAPIUser()
|
||||||
|
|
||||||
|
hostname := utils.GetHost(gc)
|
||||||
if !envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) {
|
if !envstore.EnvInMemoryStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) {
|
||||||
// insert verification request
|
// insert verification request
|
||||||
verificationType := constants.VerificationTypeBasicAuthSignup
|
verificationType := constants.VerificationTypeBasicAuthSignup
|
||||||
verificationToken, err := token.CreateVerificationToken(params.Email, verificationType)
|
verificationToken, err := token.CreateVerificationToken(params.Email, verificationType, hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Println(`error generating token`, err)
|
||||||
}
|
}
|
||||||
|
@ -135,7 +136,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
email.SendVerificationMail(params.Email, verificationToken)
|
email.SendVerificationMail(params.Email, verificationToken, hostname)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
res = &model.AuthResponse{
|
res = &model.AuthResponse{
|
||||||
|
|
|
@ -13,6 +13,8 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/db"
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
|
"github.com/authorizerdev/authorizer/server/oauth"
|
||||||
|
"github.com/authorizerdev/authorizer/server/sessionstore"
|
||||||
"github.com/authorizerdev/authorizer/server/token"
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
"github.com/authorizerdev/authorizer/server/utils"
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
)
|
)
|
||||||
|
@ -115,6 +117,8 @@ func UpdateEnvResolver(ctx context.Context, params model.UpdateEnvInput) (*model
|
||||||
|
|
||||||
// Update local store
|
// Update local store
|
||||||
envstore.EnvInMemoryStoreObj.UpdateEnvStore(updatedData)
|
envstore.EnvInMemoryStoreObj.UpdateEnvStore(updatedData)
|
||||||
|
sessionstore.InitSession()
|
||||||
|
oauth.InitOAuth()
|
||||||
|
|
||||||
// Fetch the current db store and update it
|
// Fetch the current db store and update it
|
||||||
env, err := db.Provider.GetEnv()
|
env, err := db.Provider.GetEnv()
|
||||||
|
|
|
@ -116,12 +116,13 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
|
||||||
sessionstore.DeleteAllUserSession(fmt.Sprintf("%v", user.ID))
|
sessionstore.DeleteAllUserSession(fmt.Sprintf("%v", user.ID))
|
||||||
cookie.DeleteCookie(gc)
|
cookie.DeleteCookie(gc)
|
||||||
|
|
||||||
|
hostname := utils.GetHost(gc)
|
||||||
user.Email = newEmail
|
user.Email = newEmail
|
||||||
user.EmailVerifiedAt = nil
|
user.EmailVerifiedAt = nil
|
||||||
hasEmailChanged = true
|
hasEmailChanged = true
|
||||||
// insert verification request
|
// insert verification request
|
||||||
verificationType := constants.VerificationTypeUpdateEmail
|
verificationType := constants.VerificationTypeUpdateEmail
|
||||||
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType)
|
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Println(`error generating token`, err)
|
||||||
}
|
}
|
||||||
|
@ -134,7 +135,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
email.SendVerificationMail(newEmail, verificationToken)
|
email.SendVerificationMail(newEmail, verificationToken, hostname)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,11 +98,12 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
||||||
sessionstore.DeleteAllUserSession(fmt.Sprintf("%v", user.ID))
|
sessionstore.DeleteAllUserSession(fmt.Sprintf("%v", user.ID))
|
||||||
cookie.DeleteCookie(gc)
|
cookie.DeleteCookie(gc)
|
||||||
|
|
||||||
|
hostname := utils.GetHost(gc)
|
||||||
user.Email = newEmail
|
user.Email = newEmail
|
||||||
user.EmailVerifiedAt = nil
|
user.EmailVerifiedAt = nil
|
||||||
// insert verification request
|
// insert verification request
|
||||||
verificationType := constants.VerificationTypeUpdateEmail
|
verificationType := constants.VerificationTypeUpdateEmail
|
||||||
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType)
|
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(`error generating token`, err)
|
log.Println(`error generating token`, err)
|
||||||
}
|
}
|
||||||
|
@ -115,7 +116,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
||||||
|
|
||||||
// exec it as go routin so that we can reduce the api latency
|
// exec it as go routin so that we can reduce the api latency
|
||||||
go func() {
|
go func() {
|
||||||
email.SendVerificationMail(newEmail, verificationToken)
|
email.SendVerificationMail(newEmail, verificationToken, hostname)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +128,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
||||||
inputRoles = append(inputRoles, *item)
|
inputRoles = append(inputRoles, *item)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !utils.IsValidRoles(append([]string{}, append(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles)...)...), inputRoles) {
|
if !utils.IsValidRoles(inputRoles, append([]string{}, append(envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyRoles), envstore.EnvInMemoryStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyProtectedRoles)...)...)) {
|
||||||
return res, fmt.Errorf("invalid list of roles")
|
return res, fmt.Errorf("invalid list of roles")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,13 @@ package routes
|
||||||
import (
|
import (
|
||||||
"github.com/authorizerdev/authorizer/server/handlers"
|
"github.com/authorizerdev/authorizer/server/handlers"
|
||||||
"github.com/authorizerdev/authorizer/server/middlewares"
|
"github.com/authorizerdev/authorizer/server/middlewares"
|
||||||
"github.com/gin-contrib/location"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitRouter initializes gin router
|
// InitRouter initializes gin router
|
||||||
func InitRouter() *gin.Engine {
|
func InitRouter() *gin.Engine {
|
||||||
router := gin.Default()
|
router := gin.Default()
|
||||||
router.Use(location.Default())
|
// router.Use(location.Default())
|
||||||
router.Use(middlewares.GinContextToContextMiddleware())
|
router.Use(middlewares.GinContextToContextMiddleware())
|
||||||
router.Use(middlewares.CORSMiddleware())
|
router.Use(middlewares.CORSMiddleware())
|
||||||
|
|
||||||
|
@ -25,14 +24,16 @@ func InitRouter() *gin.Engine {
|
||||||
// login page app related routes.
|
// login page app related routes.
|
||||||
app := router.Group("/app")
|
app := router.Group("/app")
|
||||||
{
|
{
|
||||||
|
app.Static("/favicon_io", "app/favicon_io")
|
||||||
app.Static("/build", "app/build")
|
app.Static("/build", "app/build")
|
||||||
app.GET("/", handlers.AppHandler())
|
app.GET("/", handlers.AppHandler())
|
||||||
app.GET("/reset-password", handlers.AppHandler())
|
app.GET("/:page", handlers.AppHandler())
|
||||||
}
|
}
|
||||||
|
|
||||||
// dashboard related routes
|
// dashboard related routes
|
||||||
dashboard := router.Group("/dashboard")
|
dashboard := router.Group("/dashboard")
|
||||||
{
|
{
|
||||||
|
dashboard.Static("/favicon_io", "dashboard/favicon_io")
|
||||||
dashboard.Static("/build", "dashboard/build")
|
dashboard.Static("/build", "dashboard/build")
|
||||||
dashboard.GET("/", handlers.DashboardHandler())
|
dashboard.GET("/", handlers.DashboardHandler())
|
||||||
dashboard.GET("/:page", handlers.DashboardHandler())
|
dashboard.GET("/:page", handlers.DashboardHandler())
|
||||||
|
|
|
@ -7,13 +7,12 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/envstore"
|
"github.com/authorizerdev/authorizer/server/envstore"
|
||||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
"github.com/authorizerdev/authorizer/server/resolvers"
|
"github.com/authorizerdev/authorizer/server/resolvers"
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func adminSignupTests(t *testing.T, s TestSetup) {
|
func adminSignupTests(t *testing.T, s TestSetup) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
t.Run(`should complete admin login`, func(t *testing.T) {
|
t.Run(`should complete admin signup`, func(t *testing.T) {
|
||||||
_, ctx := createContext(s)
|
_, ctx := createContext(s)
|
||||||
_, err := resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
_, err := resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
||||||
AdminSecret: "admin",
|
AdminSecret: "admin",
|
||||||
|
@ -24,7 +23,7 @@ func adminSignupTests(t *testing.T, s TestSetup) {
|
||||||
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyAdminSecret, "")
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyAdminSecret, "")
|
||||||
|
|
||||||
_, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
_, err = resolvers.AdminSignupResolver(ctx, model.AdminSignupInput{
|
||||||
AdminSecret: uuid.New().String(),
|
AdminSecret: "admin123",
|
||||||
})
|
})
|
||||||
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
|
@ -14,16 +14,13 @@ func TestEnvs(t *testing.T) {
|
||||||
env.InitEnv()
|
env.InitEnv()
|
||||||
store := envstore.EnvInMemoryStoreObj.GetEnvStoreClone()
|
store := envstore.EnvInMemoryStoreObj.GetEnvStoreClone()
|
||||||
|
|
||||||
assert.Equal(t, store.StringEnv[constants.EnvKeyAdminSecret], "admin")
|
|
||||||
assert.Equal(t, store.StringEnv[constants.EnvKeyEnv], "production")
|
assert.Equal(t, store.StringEnv[constants.EnvKeyEnv], "production")
|
||||||
assert.False(t, store.BoolEnv[constants.EnvKeyDisableEmailVerification])
|
assert.False(t, store.BoolEnv[constants.EnvKeyDisableEmailVerification])
|
||||||
assert.False(t, store.BoolEnv[constants.EnvKeyDisableMagicLinkLogin])
|
assert.False(t, store.BoolEnv[constants.EnvKeyDisableMagicLinkLogin])
|
||||||
assert.False(t, store.BoolEnv[constants.EnvKeyDisableBasicAuthentication])
|
assert.False(t, store.BoolEnv[constants.EnvKeyDisableBasicAuthentication])
|
||||||
assert.Equal(t, store.StringEnv[constants.EnvKeyJwtType], "HS256")
|
assert.Equal(t, store.StringEnv[constants.EnvKeyJwtType], "HS256")
|
||||||
assert.Equal(t, store.StringEnv[constants.EnvKeyJwtSecret], "random_string")
|
|
||||||
assert.Equal(t, store.StringEnv[constants.EnvKeyJwtRoleClaim], "role")
|
assert.Equal(t, store.StringEnv[constants.EnvKeyJwtRoleClaim], "role")
|
||||||
assert.EqualValues(t, store.SliceEnv[constants.EnvKeyRoles], []string{"user"})
|
assert.EqualValues(t, store.SliceEnv[constants.EnvKeyRoles], []string{"user"})
|
||||||
assert.EqualValues(t, store.SliceEnv[constants.EnvKeyDefaultRoles], []string{"user"})
|
assert.EqualValues(t, store.SliceEnv[constants.EnvKeyDefaultRoles], []string{"user"})
|
||||||
assert.EqualValues(t, store.SliceEnv[constants.EnvKeyProtectedRoles], []string{"admin"})
|
|
||||||
assert.EqualValues(t, store.SliceEnv[constants.EnvKeyAllowedOrigins], []string{"*"})
|
assert.EqualValues(t, store.SliceEnv[constants.EnvKeyAllowedOrigins], []string{"*"})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
@ -20,20 +21,20 @@ func TestResolvers(t *testing.T) {
|
||||||
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseURL, dbURL)
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseURL, dbURL)
|
||||||
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseType, dbType)
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyDatabaseType, dbType)
|
||||||
|
|
||||||
env.InitEnv()
|
s := testSetup()
|
||||||
|
defer s.Server.Close()
|
||||||
|
|
||||||
db.InitDB()
|
db.InitDB()
|
||||||
|
|
||||||
// clean the persisted config for test to use fresh config
|
// clean the persisted config for test to use fresh config
|
||||||
envData, err := db.Provider.GetEnv()
|
envData, err := db.Provider.GetEnv()
|
||||||
|
log.Println("=> envData:", envstore.EnvInMemoryStoreObj.GetEnvStoreClone())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
envData.EnvData = ""
|
envData.EnvData = ""
|
||||||
db.Provider.UpdateEnv(envData)
|
db.Provider.UpdateEnv(envData)
|
||||||
}
|
}
|
||||||
env.PersistEnv()
|
env.PersistEnv()
|
||||||
|
|
||||||
s := testSetup()
|
|
||||||
defer s.Server.Close()
|
|
||||||
|
|
||||||
t.Run("should pass tests for "+dbType, func(t *testing.T) {
|
t.Run("should pass tests for "+dbType, func(t *testing.T) {
|
||||||
// admin tests
|
// admin tests
|
||||||
adminSignupTests(t, s)
|
adminSignupTests(t, s)
|
||||||
|
|
|
@ -14,7 +14,6 @@ import (
|
||||||
"github.com/authorizerdev/authorizer/server/handlers"
|
"github.com/authorizerdev/authorizer/server/handlers"
|
||||||
"github.com/authorizerdev/authorizer/server/middlewares"
|
"github.com/authorizerdev/authorizer/server/middlewares"
|
||||||
"github.com/authorizerdev/authorizer/server/sessionstore"
|
"github.com/authorizerdev/authorizer/server/sessionstore"
|
||||||
"github.com/gin-contrib/location"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -73,13 +72,17 @@ func testSetup() TestSetup {
|
||||||
}
|
}
|
||||||
|
|
||||||
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEnvPath, "../../.env.sample")
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeyEnvPath, "../../.env.sample")
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeySmtpHost, "smtp.yopmail.com")
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeySmtpPort, "2525")
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeySmtpUsername, "lakhan@yopmail.com")
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeySmtpPassword, "test")
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.StringStoreIdentifier, constants.EnvKeySenderEmail, "info@yopmail.com")
|
||||||
|
envstore.EnvInMemoryStoreObj.UpdateEnvVariable(constants.SliceStoreIdentifier, constants.EnvKeyProtectedRoles, []string{"admin"})
|
||||||
env.InitEnv()
|
env.InitEnv()
|
||||||
sessionstore.InitSession()
|
sessionstore.InitSession()
|
||||||
|
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
c, r := gin.CreateTestContext(w)
|
c, r := gin.CreateTestContext(w)
|
||||||
r.Use(location.Default())
|
|
||||||
r.Use(middlewares.GinContextToContextMiddleware())
|
r.Use(middlewares.GinContextToContextMiddleware())
|
||||||
r.Use(middlewares.CORSMiddleware())
|
r.Use(middlewares.CORSMiddleware())
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ func updateUserTest(t *testing.T, s TestSetup) {
|
||||||
})
|
})
|
||||||
|
|
||||||
user := *signupRes.User
|
user := *signupRes.User
|
||||||
adminRole := "admin"
|
adminRole := "supplier"
|
||||||
userRole := "user"
|
userRole := "user"
|
||||||
newRoles := []*string{&adminRole, &userRole}
|
newRoles := []*string{&adminRole, &userRole}
|
||||||
_, err := resolvers.UpdateUserResolver(ctx, model.UpdateUserInput{
|
_, err := resolvers.UpdateUserResolver(ctx, model.UpdateUserInput{
|
||||||
|
|
|
@ -8,9 +8,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetHostName(t *testing.T) {
|
func TestGetHostName(t *testing.T) {
|
||||||
authorizer_url := "http://test.herokuapp.com:80"
|
url := "http://test.herokuapp.com:80"
|
||||||
|
|
||||||
host, port := utils.GetHostParts(authorizer_url)
|
host, port := utils.GetHostParts(url)
|
||||||
expectedHost := "test.herokuapp.com"
|
expectedHost := "test.herokuapp.com"
|
||||||
|
|
||||||
assert.Equal(t, host, expectedHost, "hostname should be equal")
|
assert.Equal(t, host, expectedHost, "hostname should be equal")
|
||||||
|
@ -18,9 +18,9 @@ func TestGetHostName(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetDomainName(t *testing.T) {
|
func TestGetDomainName(t *testing.T) {
|
||||||
authorizer_url := "http://test.herokuapp.com"
|
url := "http://test.herokuapp.com"
|
||||||
|
|
||||||
got := utils.GetDomainName(authorizer_url)
|
got := utils.GetDomainName(url)
|
||||||
want := "herokuapp.com"
|
want := "herokuapp.com"
|
||||||
|
|
||||||
assert.Equal(t, got, want, "domain name should be equal")
|
assert.Equal(t, got, want, "domain name should be equal")
|
||||||
|
|
|
@ -2,7 +2,6 @@ package token
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/authorizerdev/authorizer/server/constants"
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
"github.com/authorizerdev/authorizer/server/cookie"
|
"github.com/authorizerdev/authorizer/server/cookie"
|
||||||
|
@ -25,7 +24,7 @@ func GetAdminAuthToken(gc *gin.Context) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
err = bcrypt.CompareHashAndPassword([]byte(token), []byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)))
|
err = bcrypt.CompareHashAndPassword([]byte(token), []byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAdminSecret)))
|
||||||
log.Println("error comparing hash:", err)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf(`unauthorized`)
|
return "", fmt.Errorf(`unauthorized`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ type CustomClaim struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateVerificationToken creates a verification JWT token
|
// CreateVerificationToken creates a verification JWT token
|
||||||
func CreateVerificationToken(email string, tokenType string) (string, error) {
|
func CreateVerificationToken(email, tokenType, hostname string) (string, error) {
|
||||||
t := jwt.New(jwt.GetSigningMethod(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtType)))
|
t := jwt.New(jwt.GetSigningMethod(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtType)))
|
||||||
|
|
||||||
t.Claims = &CustomClaim{
|
t.Claims = &CustomClaim{
|
||||||
|
@ -31,7 +31,7 @@ func CreateVerificationToken(email string, tokenType string) (string, error) {
|
||||||
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
||||||
},
|
},
|
||||||
tokenType,
|
tokenType,
|
||||||
VerificationRequestToken{Email: email, Host: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAuthorizerURL), RedirectURL: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAppURL)},
|
VerificationRequestToken{Email: email, Host: hostname, RedirectURL: envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAppURL)},
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.SignedString([]byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret)))
|
return t.SignedString([]byte(envstore.EnvInMemoryStoreObj.GetStringStoreEnvVariable(constants.EnvKeyJwtSecret)))
|
||||||
|
|
|
@ -34,3 +34,16 @@ func SaveSessionInDB(userId string, c *gin.Context) {
|
||||||
log.Println("=> session saved in db:", sessionData)
|
log.Println("=> session saved in db:", sessionData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveDuplicateString removes duplicate strings from a string slice
|
||||||
|
func RemoveDuplicateString(strSlice []string) []string {
|
||||||
|
allKeys := make(map[string]bool)
|
||||||
|
list := []string{}
|
||||||
|
for _, item := range strSlice {
|
||||||
|
if _, value := allKeys[item]; !value {
|
||||||
|
allKeys[item] = true
|
||||||
|
list = append(list, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,23 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"log"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GetHost returns hostname from request context
|
||||||
|
func GetHost(c *gin.Context) string {
|
||||||
|
scheme := "http"
|
||||||
|
if c.Request.TLS != nil {
|
||||||
|
scheme = "https"
|
||||||
|
}
|
||||||
|
log.Println("=> url:", scheme+"://"+c.Request.Host)
|
||||||
|
return scheme + "://" + c.Request.Host
|
||||||
|
}
|
||||||
|
|
||||||
// GetHostName function returns hostname and port
|
// GetHostName function returns hostname and port
|
||||||
func GetHostParts(uri string) (string, string) {
|
func GetHostParts(uri string) (string, string) {
|
||||||
tempURI := uri
|
tempURI := uri
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
<title>{{.data.organizationName}}</title>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/app/favicon_io/apple-touch-icon.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/app/favicon_io/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/app/favicon_io/favicon-16x16.png">
|
||||||
<title>Document</title>
|
<title>Document</title>
|
||||||
<link rel="stylesheet" href="/app/build/index.css">
|
<link rel="stylesheet" href="/app/build/index.css">
|
||||||
<script>
|
<script>
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
|
<title>Authorizer | Dashboard</title>
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/dashboard/favicon_io/apple-touch-icon.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/dashboard/favicon_io/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/dashboard/favicon_io/favicon-16x16.png">
|
||||||
<title>Document</title>
|
<title>Document</title>
|
||||||
<script>
|
<script>
|
||||||
window.__authorizer__ = {{.data}}
|
window.__authorizer__ = {{.data}}
|
||||||
|
|