Feat: Add oauth2 for twitch (#426)

* fix:
* removed fmt.Println

* Feat:
- Add OAuth for twitch

---------

Co-authored-by: lemonScaletech <anand.panigrahi@scaletech.xyz>
Co-authored-by: Anand Kumar Panigrahi <70533637+lemonScaletech@users.noreply.github.com>
This commit is contained in:
scaletech-milan 2023-12-02 12:21:53 +05:30 committed by GitHub
parent 7f6ddca3fc
commit e49e315967
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 363 additions and 7 deletions

View File

@ -17,6 +17,7 @@ import {
FaApple, FaApple,
FaTwitter, FaTwitter,
FaMicrosoft, FaMicrosoft,
FaTwitch,
} from 'react-icons/fa'; } from 'react-icons/fa';
import { import {
TextInputType, TextInputType,
@ -397,6 +398,44 @@ const OAuthConfig = ({
/> />
</Center> </Center>
</Flex> </Flex>
<Flex direction={isNotSmallerScreen ? 'row' : 'column'}>
<Center
w={isNotSmallerScreen ? '55px' : '35px'}
h="35px"
marginRight="1.5%"
border="1px solid #3b5998"
borderRadius="5px"
>
<FaTwitch />
</Center>
<Center
w={isNotSmallerScreen ? '70%' : '100%'}
mt={isNotSmallerScreen ? '0' : '3'}
marginRight="1.5%"
>
<InputField
borderRadius={5}
variables={envVariables}
setVariables={setVariables}
inputType={TextInputType.TWITCH_CLIENT_ID}
placeholder="Twitch Client ID"
/>
</Center>
<Center
w={isNotSmallerScreen ? '70%' : '100%'}
mt={isNotSmallerScreen ? '0' : '3'}
>
<InputField
borderRadius={5}
variables={envVariables}
setVariables={setVariables}
fieldVisibility={fieldVisibility}
setFieldVisibility={setFieldVisibility}
inputType={HiddenInputType.TWITCH_CLIENT_SECRET}
placeholder="Twitch Client Secret"
/>
</Center>
</Flex>
</Stack> </Stack>
</Box> </Box>
</div> </div>

View File

@ -12,6 +12,7 @@ export const TextInputType = {
TWITTER_CLIENT_ID: 'TWITTER_CLIENT_ID', TWITTER_CLIENT_ID: 'TWITTER_CLIENT_ID',
MICROSOFT_CLIENT_ID: 'MICROSOFT_CLIENT_ID', MICROSOFT_CLIENT_ID: 'MICROSOFT_CLIENT_ID',
MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: 'MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID', MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: 'MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID',
TWITCH_CLIENT_ID: 'TWITCH_CLIENT_ID',
JWT_ROLE_CLAIM: 'JWT_ROLE_CLAIM', JWT_ROLE_CLAIM: 'JWT_ROLE_CLAIM',
REDIS_URL: 'REDIS_URL', REDIS_URL: 'REDIS_URL',
SMTP_HOST: 'SMTP_HOST', SMTP_HOST: 'SMTP_HOST',
@ -42,6 +43,7 @@ export const HiddenInputType = {
APPLE_CLIENT_SECRET: 'APPLE_CLIENT_SECRET', APPLE_CLIENT_SECRET: 'APPLE_CLIENT_SECRET',
TWITTER_CLIENT_SECRET: 'TWITTER_CLIENT_SECRET', TWITTER_CLIENT_SECRET: 'TWITTER_CLIENT_SECRET',
MICROSOFT_CLIENT_SECRET: 'MICROSOFT_CLIENT_SECRET', MICROSOFT_CLIENT_SECRET: 'MICROSOFT_CLIENT_SECRET',
TWITCH_CLIENT_SECRET: 'TWITCH_CLIENT_SECRET',
JWT_SECRET: 'JWT_SECRET', JWT_SECRET: 'JWT_SECRET',
SMTP_PASSWORD: 'SMTP_PASSWORD', SMTP_PASSWORD: 'SMTP_PASSWORD',
ADMIN_SECRET: 'ADMIN_SECRET', ADMIN_SECRET: 'ADMIN_SECRET',
@ -132,6 +134,8 @@ export interface envVarTypes {
MICROSOFT_CLIENT_ID: string; MICROSOFT_CLIENT_ID: string;
MICROSOFT_CLIENT_SECRET: string; MICROSOFT_CLIENT_SECRET: string;
MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: string; MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: string;
TWITCH_CLIENT_ID: string;
TWITCH_CLIENT_SECRET: string;
ROLES: [string] | []; ROLES: [string] | [];
DEFAULT_ROLES: [string] | []; DEFAULT_ROLES: [string] | [];
PROTECTED_ROLES: [string] | []; PROTECTED_ROLES: [string] | [];

View File

@ -35,6 +35,8 @@ export const EnvVariablesQuery = `
MICROSOFT_CLIENT_ID MICROSOFT_CLIENT_ID
MICROSOFT_CLIENT_SECRET MICROSOFT_CLIENT_SECRET
MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID
TWITCH_CLIENT_ID
TWITCH_CLIENT_SECRET
DEFAULT_ROLES DEFAULT_ROLES
PROTECTED_ROLES PROTECTED_ROLES
ROLES ROLES

View File

@ -55,6 +55,8 @@ const Environment = () => {
MICROSOFT_CLIENT_ID: '', MICROSOFT_CLIENT_ID: '',
MICROSOFT_CLIENT_SECRET: '', MICROSOFT_CLIENT_SECRET: '',
MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: '', MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: '',
TWITCH_CLIENT_ID: '',
TWITCH_CLIENT_SECRET: '',
ROLES: [], ROLES: [],
DEFAULT_ROLES: [], DEFAULT_ROLES: [],
PROTECTED_ROLES: [], PROTECTED_ROLES: [],
@ -107,6 +109,7 @@ const Environment = () => {
LINKEDIN_CLIENT_SECRET: false, LINKEDIN_CLIENT_SECRET: false,
APPLE_CLIENT_SECRET: false, APPLE_CLIENT_SECRET: false,
TWITTER_CLIENT_SECRET: false, TWITTER_CLIENT_SECRET: false,
TWITCH_CLIENT_SECRET: false,
JWT_SECRET: false, JWT_SECRET: false,
SMTP_PASSWORD: false, SMTP_PASSWORD: false,
ADMIN_SECRET: false, ADMIN_SECRET: false,

View File

@ -23,4 +23,6 @@ const (
AuthRecipeMethodTwitter = "twitter" AuthRecipeMethodTwitter = "twitter"
// AuthRecipeMethodMicrosoft is the microsoft auth method // AuthRecipeMethodMicrosoft is the microsoft auth method
AuthRecipeMethodMicrosoft = "microsoft" AuthRecipeMethodMicrosoft = "microsoft"
// AuthRecipeMethodTwitch is the twitch auth method
AuthRecipeMethodTwitch = "twitch"
) )

View File

@ -118,6 +118,10 @@ const (
EnvKeyMicrosoftActiveDirectoryTenantID = "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID" EnvKeyMicrosoftActiveDirectoryTenantID = "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID"
// EnvKeyMicrosoftClientSecret key for env variable MICROSOFT_CLIENT_SECRET // EnvKeyMicrosoftClientSecret key for env variable MICROSOFT_CLIENT_SECRET
EnvKeyMicrosoftClientSecret = "MICROSOFT_CLIENT_SECRET" EnvKeyMicrosoftClientSecret = "MICROSOFT_CLIENT_SECRET"
// EnvKeyTwitchClientID key for env variable TWITCH_CLIENT_ID
EnvKeyTwitchClientID = "TWITCH_CLIENT_ID"
// EnvKeyTwitchClientSecret key for env variable TWITCH_CLIENT_SECRET
EnvKeyTwitchClientSecret = "TWITCH_CLIENT_SECRET"
// EnvKeyOrganizationName key for env variable ORGANIZATION_NAME // EnvKeyOrganizationName key for env variable ORGANIZATION_NAME
EnvKeyOrganizationName = "ORGANIZATION_NAME" EnvKeyOrganizationName = "ORGANIZATION_NAME"
// EnvKeyOrganizationLogo key for env variable ORGANIZATION_LOGO // EnvKeyOrganizationLogo key for env variable ORGANIZATION_LOGO

View File

@ -139,6 +139,8 @@ type ComplexityRoot struct {
SMTPUsername func(childComplexity int) int SMTPUsername func(childComplexity int) int
SenderEmail func(childComplexity int) int SenderEmail func(childComplexity int) int
SenderName func(childComplexity int) int SenderName func(childComplexity int) int
TwitchClientID func(childComplexity int) int
TwitchClientSecret func(childComplexity int) int
TwitterClientID func(childComplexity int) int TwitterClientID func(childComplexity int) int
TwitterClientSecret func(childComplexity int) int TwitterClientSecret func(childComplexity int) int
} }
@ -173,6 +175,7 @@ type ComplexityRoot struct {
IsMultiFactorAuthEnabled func(childComplexity int) int IsMultiFactorAuthEnabled func(childComplexity int) int
IsSignUpEnabled func(childComplexity int) int IsSignUpEnabled func(childComplexity int) int
IsStrongPasswordEnabled func(childComplexity int) int IsStrongPasswordEnabled func(childComplexity int) int
IsTwitchLoginEnabled func(childComplexity int) int
IsTwitterLoginEnabled func(childComplexity int) int IsTwitterLoginEnabled func(childComplexity int) int
Version func(childComplexity int) int Version func(childComplexity int) int
} }
@ -992,6 +995,20 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Env.SenderName(childComplexity), true return e.complexity.Env.SenderName(childComplexity), true
case "Env.TWITCH_CLIENT_ID":
if e.complexity.Env.TwitchClientID == nil {
break
}
return e.complexity.Env.TwitchClientID(childComplexity), true
case "Env.TWITCH_CLIENT_SECRET":
if e.complexity.Env.TwitchClientSecret == nil {
break
}
return e.complexity.Env.TwitchClientSecret(childComplexity), true
case "Env.TWITTER_CLIENT_ID": case "Env.TWITTER_CLIENT_ID":
if e.complexity.Env.TwitterClientID == nil { if e.complexity.Env.TwitterClientID == nil {
break break
@ -1146,6 +1163,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Meta.IsStrongPasswordEnabled(childComplexity), true return e.complexity.Meta.IsStrongPasswordEnabled(childComplexity), true
case "Meta.is_twitch_login_enabled":
if e.complexity.Meta.IsTwitchLoginEnabled == nil {
break
}
return e.complexity.Meta.IsTwitchLoginEnabled(childComplexity), true
case "Meta.is_twitter_login_enabled": case "Meta.is_twitter_login_enabled":
if e.complexity.Meta.IsTwitterLoginEnabled == nil { if e.complexity.Meta.IsTwitterLoginEnabled == nil {
break break
@ -2324,6 +2348,7 @@ type Meta {
is_apple_login_enabled: Boolean! is_apple_login_enabled: Boolean!
is_twitter_login_enabled: Boolean! is_twitter_login_enabled: Boolean!
is_microsoft_login_enabled: Boolean! is_microsoft_login_enabled: Boolean!
is_twitch_login_enabled: Boolean!
is_email_verification_enabled: Boolean! is_email_verification_enabled: Boolean!
is_basic_authentication_enabled: Boolean! is_basic_authentication_enabled: Boolean!
is_magic_link_login_enabled: Boolean! is_magic_link_login_enabled: Boolean!
@ -2477,6 +2502,8 @@ type Env {
MICROSOFT_CLIENT_ID: String MICROSOFT_CLIENT_ID: String
MICROSOFT_CLIENT_SECRET: String MICROSOFT_CLIENT_SECRET: String
MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: String MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: String
TWITCH_CLIENT_ID: String
TWITCH_CLIENT_SECRET: String
ORGANIZATION_NAME: String ORGANIZATION_NAME: String
ORGANIZATION_LOGO: String ORGANIZATION_LOGO: String
APP_COOKIE_SECURE: Boolean! APP_COOKIE_SECURE: Boolean!
@ -2604,6 +2631,8 @@ input UpdateEnvInput {
MICROSOFT_CLIENT_ID: String MICROSOFT_CLIENT_ID: String
MICROSOFT_CLIENT_SECRET: String MICROSOFT_CLIENT_SECRET: String
MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: String MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: String
TWITCH_CLIENT_ID: String
TWITCH_CLIENT_SECRET: String
ORGANIZATION_NAME: String ORGANIZATION_NAME: String
ORGANIZATION_LOGO: String ORGANIZATION_LOGO: String
DEFAULT_AUTHORIZE_RESPONSE_TYPE: String DEFAULT_AUTHORIZE_RESPONSE_TYPE: String
@ -6833,6 +6862,88 @@ func (ec *executionContext) fieldContext_Env_MICROSOFT_ACTIVE_DIRECTORY_TENANT_I
return fc, nil return fc, nil
} }
func (ec *executionContext) _Env_TWITCH_CLIENT_ID(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Env_TWITCH_CLIENT_ID(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.TwitchClientID, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Env_TWITCH_CLIENT_ID(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Env_TWITCH_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Env_TWITCH_CLIENT_SECRET(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.TwitchClientSecret, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Env_TWITCH_CLIENT_SECRET(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Env",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Env_ORGANIZATION_NAME(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) { func (ec *executionContext) _Env_ORGANIZATION_NAME(ctx context.Context, field graphql.CollectedField, obj *model.Env) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Env_ORGANIZATION_NAME(ctx, field) fc, err := ec.fieldContext_Env_ORGANIZATION_NAME(ctx, field)
if err != nil { if err != nil {
@ -7954,6 +8065,50 @@ func (ec *executionContext) fieldContext_Meta_is_microsoft_login_enabled(ctx con
return fc, nil return fc, nil
} }
func (ec *executionContext) _Meta_is_twitch_login_enabled(ctx context.Context, field graphql.CollectedField, obj *model.Meta) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Meta_is_twitch_login_enabled(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return obj.IsTwitchLoginEnabled, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(bool)
fc.Result = res
return ec.marshalNBoolean2bool(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Meta_is_twitch_login_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Meta",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type Boolean does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _Meta_is_email_verification_enabled(ctx context.Context, field graphql.CollectedField, obj *model.Meta) (ret graphql.Marshaler) { func (ec *executionContext) _Meta_is_email_verification_enabled(ctx context.Context, field graphql.CollectedField, obj *model.Meta) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Meta_is_email_verification_enabled(ctx, field) fc, err := ec.fieldContext_Meta_is_email_verification_enabled(ctx, field)
if err != nil { if err != nil {
@ -10484,6 +10639,8 @@ func (ec *executionContext) fieldContext_Query_meta(ctx context.Context, field g
return ec.fieldContext_Meta_is_twitter_login_enabled(ctx, field) return ec.fieldContext_Meta_is_twitter_login_enabled(ctx, field)
case "is_microsoft_login_enabled": case "is_microsoft_login_enabled":
return ec.fieldContext_Meta_is_microsoft_login_enabled(ctx, field) return ec.fieldContext_Meta_is_microsoft_login_enabled(ctx, field)
case "is_twitch_login_enabled":
return ec.fieldContext_Meta_is_twitch_login_enabled(ctx, field)
case "is_email_verification_enabled": case "is_email_verification_enabled":
return ec.fieldContext_Meta_is_email_verification_enabled(ctx, field) return ec.fieldContext_Meta_is_email_verification_enabled(ctx, field)
case "is_basic_authentication_enabled": case "is_basic_authentication_enabled":
@ -11208,6 +11365,10 @@ func (ec *executionContext) fieldContext_Query__env(ctx context.Context, field g
return ec.fieldContext_Env_MICROSOFT_CLIENT_SECRET(ctx, field) return ec.fieldContext_Env_MICROSOFT_CLIENT_SECRET(ctx, field)
case "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID": case "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID":
return ec.fieldContext_Env_MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID(ctx, field) return ec.fieldContext_Env_MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID(ctx, field)
case "TWITCH_CLIENT_ID":
return ec.fieldContext_Env_TWITCH_CLIENT_ID(ctx, field)
case "TWITCH_CLIENT_SECRET":
return ec.fieldContext_Env_TWITCH_CLIENT_SECRET(ctx, field)
case "ORGANIZATION_NAME": case "ORGANIZATION_NAME":
return ec.fieldContext_Env_ORGANIZATION_NAME(ctx, field) return ec.fieldContext_Env_ORGANIZATION_NAME(ctx, field)
case "ORGANIZATION_LOGO": case "ORGANIZATION_LOGO":
@ -17715,7 +17876,7 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"ACCESS_TOKEN_EXPIRY_TIME", "ADMIN_SECRET", "CUSTOM_ACCESS_TOKEN_SCRIPT", "OLD_ADMIN_SECRET", "SMTP_HOST", "SMTP_PORT", "SMTP_USERNAME", "SMTP_PASSWORD", "SMTP_LOCAL_NAME", "SENDER_EMAIL", "SENDER_NAME", "JWT_TYPE", "JWT_SECRET", "JWT_PRIVATE_KEY", "JWT_PUBLIC_KEY", "ALLOWED_ORIGINS", "APP_URL", "RESET_PASSWORD_URL", "APP_COOKIE_SECURE", "ADMIN_COOKIE_SECURE", "DISABLE_EMAIL_VERIFICATION", "DISABLE_BASIC_AUTHENTICATION", "DISABLE_MAGIC_LINK_LOGIN", "DISABLE_LOGIN_PAGE", "DISABLE_SIGN_UP", "DISABLE_REDIS_FOR_ENV", "DISABLE_STRONG_PASSWORD", "DISABLE_MULTI_FACTOR_AUTHENTICATION", "ENFORCE_MULTI_FACTOR_AUTHENTICATION", "ROLES", "PROTECTED_ROLES", "DEFAULT_ROLES", "JWT_ROLE_CLAIM", "GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", "GITHUB_CLIENT_ID", "GITHUB_CLIENT_SECRET", "FACEBOOK_CLIENT_ID", "FACEBOOK_CLIENT_SECRET", "LINKEDIN_CLIENT_ID", "LINKEDIN_CLIENT_SECRET", "APPLE_CLIENT_ID", "APPLE_CLIENT_SECRET", "TWITTER_CLIENT_ID", "TWITTER_CLIENT_SECRET", "MICROSOFT_CLIENT_ID", "MICROSOFT_CLIENT_SECRET", "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID", "ORGANIZATION_NAME", "ORGANIZATION_LOGO", "DEFAULT_AUTHORIZE_RESPONSE_TYPE", "DEFAULT_AUTHORIZE_RESPONSE_MODE", "DISABLE_PLAYGROUND", "DISABLE_MAIL_OTP_LOGIN", "DISABLE_TOTP_LOGIN"} fieldsInOrder := [...]string{"ACCESS_TOKEN_EXPIRY_TIME", "ADMIN_SECRET", "CUSTOM_ACCESS_TOKEN_SCRIPT", "OLD_ADMIN_SECRET", "SMTP_HOST", "SMTP_PORT", "SMTP_USERNAME", "SMTP_PASSWORD", "SMTP_LOCAL_NAME", "SENDER_EMAIL", "SENDER_NAME", "JWT_TYPE", "JWT_SECRET", "JWT_PRIVATE_KEY", "JWT_PUBLIC_KEY", "ALLOWED_ORIGINS", "APP_URL", "RESET_PASSWORD_URL", "APP_COOKIE_SECURE", "ADMIN_COOKIE_SECURE", "DISABLE_EMAIL_VERIFICATION", "DISABLE_BASIC_AUTHENTICATION", "DISABLE_MAGIC_LINK_LOGIN", "DISABLE_LOGIN_PAGE", "DISABLE_SIGN_UP", "DISABLE_REDIS_FOR_ENV", "DISABLE_STRONG_PASSWORD", "DISABLE_MULTI_FACTOR_AUTHENTICATION", "ENFORCE_MULTI_FACTOR_AUTHENTICATION", "ROLES", "PROTECTED_ROLES", "DEFAULT_ROLES", "JWT_ROLE_CLAIM", "GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", "GITHUB_CLIENT_ID", "GITHUB_CLIENT_SECRET", "FACEBOOK_CLIENT_ID", "FACEBOOK_CLIENT_SECRET", "LINKEDIN_CLIENT_ID", "LINKEDIN_CLIENT_SECRET", "APPLE_CLIENT_ID", "APPLE_CLIENT_SECRET", "TWITTER_CLIENT_ID", "TWITTER_CLIENT_SECRET", "MICROSOFT_CLIENT_ID", "MICROSOFT_CLIENT_SECRET", "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID", "TWITCH_CLIENT_ID", "TWITCH_CLIENT_SECRET", "ORGANIZATION_NAME", "ORGANIZATION_LOGO", "DEFAULT_AUTHORIZE_RESPONSE_TYPE", "DEFAULT_AUTHORIZE_RESPONSE_MODE", "DISABLE_PLAYGROUND", "DISABLE_MAIL_OTP_LOGIN", "DISABLE_TOTP_LOGIN"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@ -18154,6 +18315,24 @@ func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, ob
return it, err return it, err
} }
it.MicrosoftActiveDirectoryTenantID = data it.MicrosoftActiveDirectoryTenantID = data
case "TWITCH_CLIENT_ID":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("TWITCH_CLIENT_ID"))
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
it.TwitchClientID = data
case "TWITCH_CLIENT_SECRET":
var err error
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("TWITCH_CLIENT_SECRET"))
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
it.TwitchClientSecret = data
case "ORGANIZATION_NAME": case "ORGANIZATION_NAME":
var err error var err error
@ -19136,6 +19315,10 @@ func (ec *executionContext) _Env(ctx context.Context, sel ast.SelectionSet, obj
out.Values[i] = ec._Env_MICROSOFT_CLIENT_SECRET(ctx, field, obj) out.Values[i] = ec._Env_MICROSOFT_CLIENT_SECRET(ctx, field, obj)
case "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID": case "MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID":
out.Values[i] = ec._Env_MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID(ctx, field, obj) out.Values[i] = ec._Env_MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID(ctx, field, obj)
case "TWITCH_CLIENT_ID":
out.Values[i] = ec._Env_TWITCH_CLIENT_ID(ctx, field, obj)
case "TWITCH_CLIENT_SECRET":
out.Values[i] = ec._Env_TWITCH_CLIENT_SECRET(ctx, field, obj)
case "ORGANIZATION_NAME": case "ORGANIZATION_NAME":
out.Values[i] = ec._Env_ORGANIZATION_NAME(ctx, field, obj) out.Values[i] = ec._Env_ORGANIZATION_NAME(ctx, field, obj)
case "ORGANIZATION_LOGO": case "ORGANIZATION_LOGO":
@ -19376,6 +19559,11 @@ func (ec *executionContext) _Meta(ctx context.Context, sel ast.SelectionSet, obj
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {
out.Invalids++ out.Invalids++
} }
case "is_twitch_login_enabled":
out.Values[i] = ec._Meta_is_twitch_login_enabled(ctx, field, obj)
if out.Values[i] == graphql.Null {
out.Invalids++
}
case "is_email_verification_enabled": case "is_email_verification_enabled":
out.Values[i] = ec._Meta_is_email_verification_enabled(ctx, field, obj) out.Values[i] = ec._Meta_is_email_verification_enabled(ctx, field, obj)
if out.Values[i] == graphql.Null { if out.Values[i] == graphql.Null {

View File

@ -119,6 +119,8 @@ type Env struct {
MicrosoftClientID *string `json:"MICROSOFT_CLIENT_ID,omitempty"` MicrosoftClientID *string `json:"MICROSOFT_CLIENT_ID,omitempty"`
MicrosoftClientSecret *string `json:"MICROSOFT_CLIENT_SECRET,omitempty"` MicrosoftClientSecret *string `json:"MICROSOFT_CLIENT_SECRET,omitempty"`
MicrosoftActiveDirectoryTenantID *string `json:"MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID,omitempty"` MicrosoftActiveDirectoryTenantID *string `json:"MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID,omitempty"`
TwitchClientID *string `json:"TWITCH_CLIENT_ID,omitempty"`
TwitchClientSecret *string `json:"TWITCH_CLIENT_SECRET,omitempty"`
OrganizationName *string `json:"ORGANIZATION_NAME,omitempty"` OrganizationName *string `json:"ORGANIZATION_NAME,omitempty"`
OrganizationLogo *string `json:"ORGANIZATION_LOGO,omitempty"` OrganizationLogo *string `json:"ORGANIZATION_LOGO,omitempty"`
AppCookieSecure bool `json:"APP_COOKIE_SECURE"` AppCookieSecure bool `json:"APP_COOKIE_SECURE"`
@ -198,6 +200,7 @@ type Meta struct {
IsAppleLoginEnabled bool `json:"is_apple_login_enabled"` IsAppleLoginEnabled bool `json:"is_apple_login_enabled"`
IsTwitterLoginEnabled bool `json:"is_twitter_login_enabled"` IsTwitterLoginEnabled bool `json:"is_twitter_login_enabled"`
IsMicrosoftLoginEnabled bool `json:"is_microsoft_login_enabled"` IsMicrosoftLoginEnabled bool `json:"is_microsoft_login_enabled"`
IsTwitchLoginEnabled bool `json:"is_twitch_login_enabled"`
IsEmailVerificationEnabled bool `json:"is_email_verification_enabled"` IsEmailVerificationEnabled bool `json:"is_email_verification_enabled"`
IsBasicAuthenticationEnabled bool `json:"is_basic_authentication_enabled"` IsBasicAuthenticationEnabled bool `json:"is_basic_authentication_enabled"`
IsMagicLinkLoginEnabled bool `json:"is_magic_link_login_enabled"` IsMagicLinkLoginEnabled bool `json:"is_magic_link_login_enabled"`
@ -383,6 +386,8 @@ type UpdateEnvInput struct {
MicrosoftClientID *string `json:"MICROSOFT_CLIENT_ID,omitempty"` MicrosoftClientID *string `json:"MICROSOFT_CLIENT_ID,omitempty"`
MicrosoftClientSecret *string `json:"MICROSOFT_CLIENT_SECRET,omitempty"` MicrosoftClientSecret *string `json:"MICROSOFT_CLIENT_SECRET,omitempty"`
MicrosoftActiveDirectoryTenantID *string `json:"MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID,omitempty"` MicrosoftActiveDirectoryTenantID *string `json:"MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID,omitempty"`
TwitchClientID *string `json:"TWITCH_CLIENT_ID,omitempty"`
TwitchClientSecret *string `json:"TWITCH_CLIENT_SECRET,omitempty"`
OrganizationName *string `json:"ORGANIZATION_NAME,omitempty"` OrganizationName *string `json:"ORGANIZATION_NAME,omitempty"`
OrganizationLogo *string `json:"ORGANIZATION_LOGO,omitempty"` OrganizationLogo *string `json:"ORGANIZATION_LOGO,omitempty"`
DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE,omitempty"` DefaultAuthorizeResponseType *string `json:"DEFAULT_AUTHORIZE_RESPONSE_TYPE,omitempty"`

View File

@ -22,6 +22,7 @@ type Meta {
is_apple_login_enabled: Boolean! is_apple_login_enabled: Boolean!
is_twitter_login_enabled: Boolean! is_twitter_login_enabled: Boolean!
is_microsoft_login_enabled: Boolean! is_microsoft_login_enabled: Boolean!
is_twitch_login_enabled: Boolean!
is_email_verification_enabled: Boolean! is_email_verification_enabled: Boolean!
is_basic_authentication_enabled: Boolean! is_basic_authentication_enabled: Boolean!
is_magic_link_login_enabled: Boolean! is_magic_link_login_enabled: Boolean!
@ -175,6 +176,8 @@ type Env {
MICROSOFT_CLIENT_ID: String MICROSOFT_CLIENT_ID: String
MICROSOFT_CLIENT_SECRET: String MICROSOFT_CLIENT_SECRET: String
MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: String MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: String
TWITCH_CLIENT_ID: String
TWITCH_CLIENT_SECRET: String
ORGANIZATION_NAME: String ORGANIZATION_NAME: String
ORGANIZATION_LOGO: String ORGANIZATION_LOGO: String
APP_COOKIE_SECURE: Boolean! APP_COOKIE_SECURE: Boolean!
@ -302,6 +305,8 @@ input UpdateEnvInput {
MICROSOFT_CLIENT_ID: String MICROSOFT_CLIENT_ID: String
MICROSOFT_CLIENT_SECRET: String MICROSOFT_CLIENT_SECRET: String
MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: String MICROSOFT_ACTIVE_DIRECTORY_TENANT_ID: String
TWITCH_CLIENT_ID: String
TWITCH_CLIENT_SECRET: String
ORGANIZATION_NAME: String ORGANIZATION_NAME: String
ORGANIZATION_LOGO: String ORGANIZATION_LOGO: String
DEFAULT_AUTHORIZE_RESPONSE_TYPE: String DEFAULT_AUTHORIZE_RESPONSE_TYPE: String

View File

@ -11,11 +11,13 @@ import (
"strings" "strings"
"time" "time"
"golang.org/x/oauth2"
"github.com/coreos/go-oidc/v3/oidc" "github.com/coreos/go-oidc/v3/oidc"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/google/uuid" "github.com/google/uuid"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"golang.org/x/oauth2"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/cookie" "github.com/authorizerdev/authorizer/server/cookie"
@ -75,6 +77,8 @@ func OAuthCallbackHandler() gin.HandlerFunc {
user, err = processTwitterUserInfo(ctx, oauthCode, sessionState) user, err = processTwitterUserInfo(ctx, oauthCode, sessionState)
case constants.AuthRecipeMethodMicrosoft: case constants.AuthRecipeMethodMicrosoft:
user, err = processMicrosoftUserInfo(ctx, oauthCode) user, err = processMicrosoftUserInfo(ctx, oauthCode)
case constants.AuthRecipeMethodTwitch:
user, err = processTwitchUserInfo(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`)
@ -703,3 +707,41 @@ func processMicrosoftUserInfo(ctx context.Context, code string) (*models.User, e
return user, nil return user, nil
} }
// process twitch user information
func processTwitchUserInfo(ctx context.Context, code string) (*models.User, error) {
oauth2Token, err := oauth.OAuthProviders.TwitchConfig.Exchange(ctx, code)
if err != nil {
log.Debug("Failed to exchange code for token: ", err)
return nil, fmt.Errorf("invalid twitch exchange code: %s", err.Error())
}
// Extract the ID Token from OAuth2 token.
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
log.Debug("Failed to extract ID Token from OAuth2 token")
return nil, fmt.Errorf("unable to extract id_token")
}
// we need to skip issuer check because for common tenant it will return internal issuer which does not match
verifier := oauth.OIDCProviders.TwitchOIDC.Verifier(&oidc.Config{
ClientID: oauth.OAuthProviders.TwitchConfig.ClientID,
SkipIssuerCheck: true,
})
// Parse and verify ID Token payload.
idToken, err := verifier.Verify(ctx, rawIDToken)
if err != nil {
log.Debug("Failed to verify ID Token: ", err)
return nil, fmt.Errorf("unable to verify id_token: %s", err.Error())
}
user := &models.User{}
if err := idToken.Claims(&user); err != nil {
log.Debug("Failed to parse ID Token claims: ", err)
return nil, fmt.Errorf("unable to extract claims")
}
return user, nil
}

View File

@ -4,10 +4,12 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"github.com/gin-gonic/gin"
log "github.com/sirupsen/logrus"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
"github.com/authorizerdev/authorizer/server/oauth" "github.com/authorizerdev/authorizer/server/oauth"
@ -227,6 +229,24 @@ func OAuthLoginHandler() gin.HandlerFunc {
oauth.OAuthProviders.MicrosoftConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodMicrosoft oauth.OAuthProviders.MicrosoftConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodMicrosoft
url := oauth.OAuthProviders.MicrosoftConfig.AuthCodeURL(oauthStateString) url := oauth.OAuthProviders.MicrosoftConfig.AuthCodeURL(oauthStateString)
c.Redirect(http.StatusTemporaryRedirect, url) c.Redirect(http.StatusTemporaryRedirect, url)
case constants.AuthRecipeMethodTwitch:
if oauth.OAuthProviders.TwitchConfig == nil {
log.Debug("Twitch OAuth provider is not configured")
isProviderConfigured = false
break
}
err := memorystore.Provider.SetState(oauthStateString, constants.AuthRecipeMethodTwitch)
if err != nil {
log.Debug("Error setting state: ", err)
c.JSON(500, gin.H{
"error": "internal server error",
})
return
}
// during the init of OAuthProvider authorizer url might be empty
oauth.OAuthProviders.TwitchConfig.RedirectURL = hostname + "/oauth_callback/" + constants.AuthRecipeMethodTwitch
url := oauth.OAuthProviders.TwitchConfig.AuthCodeURL(oauthStateString)
c.Redirect(http.StatusTemporaryRedirect, url)
default: default:
log.Debug("Invalid oauth provider: ", provider) log.Debug("Invalid oauth provider: ", provider)
c.JSON(422, gin.H{ c.JSON(422, gin.H{

View File

@ -4,13 +4,16 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/coreos/go-oidc/v3/oidc"
"golang.org/x/oauth2" "golang.org/x/oauth2"
"google.golang.org/appengine/log"
facebookOAuth2 "golang.org/x/oauth2/facebook" facebookOAuth2 "golang.org/x/oauth2/facebook"
githubOAuth2 "golang.org/x/oauth2/github" githubOAuth2 "golang.org/x/oauth2/github"
linkedInOAuth2 "golang.org/x/oauth2/linkedin" linkedInOAuth2 "golang.org/x/oauth2/linkedin"
microsoftOAuth2 "golang.org/x/oauth2/microsoft" microsoftOAuth2 "golang.org/x/oauth2/microsoft"
"google.golang.org/appengine/log" twitchOAuth2 "golang.org/x/oauth2/twitch"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/authorizerdev/authorizer/server/constants" "github.com/authorizerdev/authorizer/server/constants"
"github.com/authorizerdev/authorizer/server/memorystore" "github.com/authorizerdev/authorizer/server/memorystore"
@ -29,12 +32,14 @@ type OAuthProvider struct {
AppleConfig *oauth2.Config AppleConfig *oauth2.Config
TwitterConfig *oauth2.Config TwitterConfig *oauth2.Config
MicrosoftConfig *oauth2.Config MicrosoftConfig *oauth2.Config
TwitchConfig *oauth2.Config
} }
// OIDCProviders is a struct that contains reference all the OpenID providers // OIDCProviders is a struct that contains reference all the OpenID providers
type OIDCProvider struct { type OIDCProvider struct {
GoogleOIDC *oidc.Provider GoogleOIDC *oidc.Provider
MicrosoftOIDC *oidc.Provider MicrosoftOIDC *oidc.Provider
TwitchOIDC *oidc.Provider
} }
var ( var (
@ -198,5 +203,31 @@ func InitOAuth() error {
} }
} }
twitchClientID, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwitchClientID)
if err != nil {
twitchClientID = ""
}
twitchClientSecret, err := memorystore.Provider.GetStringStoreEnvVariable(constants.EnvKeyTwitchClientSecret)
if err != nil {
twitchClientSecret = ""
}
if twitchClientID != "" && twitchClientSecret != "" {
p, err := oidc.NewProvider(ctx, "https://id.twitch.tv/oauth2")
if err != nil {
log.Debugf(ctx, "Error while creating OIDC provider for Twitch: %v", err)
return err
}
OIDCProviders.TwitchOIDC = p
OAuthProviders.TwitchConfig = &oauth2.Config{
ClientID: twitchClientID,
ClientSecret: twitchClientSecret,
RedirectURL: "/oauth_callback/twitch",
Endpoint: twitchOAuth2.Endpoint,
Scopes: []string{oidc.ScopeOpenID},
}
}
return nil return nil
} }

View File

@ -164,7 +164,12 @@ func EnvResolver(ctx context.Context) (*model.Env, error) {
if val, ok := store[constants.EnvKeyMicrosoftActiveDirectoryTenantID]; ok { if val, ok := store[constants.EnvKeyMicrosoftActiveDirectoryTenantID]; ok {
res.MicrosoftActiveDirectoryTenantID = refs.NewStringRef(val.(string)) res.MicrosoftActiveDirectoryTenantID = refs.NewStringRef(val.(string))
} }
if val, ok := store[constants.EnvKeyTwitchClientID]; ok {
res.TwitchClientID = refs.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyTwitchClientSecret]; ok {
res.TwitchClientSecret = refs.NewStringRef(val.(string))
}
if val, ok := store[constants.EnvKeyOrganizationName]; ok { if val, ok := store[constants.EnvKeyOrganizationName]; ok {
res.OrganizationName = refs.NewStringRef(val.(string)) res.OrganizationName = refs.NewStringRef(val.(string))
} }

View File

@ -34,6 +34,7 @@ func clearSessionIfRequired(currentData, updatedData map[string]interface{}) {
isCurrentLinkedInLoginEnabled := currentData[constants.EnvKeyLinkedInClientID] != nil && currentData[constants.EnvKeyLinkedInClientSecret] != nil && currentData[constants.EnvKeyLinkedInClientID].(string) != "" && currentData[constants.EnvKeyLinkedInClientSecret].(string) != "" isCurrentLinkedInLoginEnabled := currentData[constants.EnvKeyLinkedInClientID] != nil && currentData[constants.EnvKeyLinkedInClientSecret] != nil && currentData[constants.EnvKeyLinkedInClientID].(string) != "" && currentData[constants.EnvKeyLinkedInClientSecret].(string) != ""
isCurrentTwitterLoginEnabled := currentData[constants.EnvKeyTwitterClientID] != nil && currentData[constants.EnvKeyTwitterClientSecret] != nil && currentData[constants.EnvKeyTwitterClientID].(string) != "" && currentData[constants.EnvKeyTwitterClientSecret].(string) != "" isCurrentTwitterLoginEnabled := currentData[constants.EnvKeyTwitterClientID] != nil && currentData[constants.EnvKeyTwitterClientSecret] != nil && currentData[constants.EnvKeyTwitterClientID].(string) != "" && currentData[constants.EnvKeyTwitterClientSecret].(string) != ""
isCurrentMicrosoftLoginEnabled := currentData[constants.EnvKeyMicrosoftClientID] != nil && currentData[constants.EnvKeyMicrosoftClientSecret] != nil && currentData[constants.EnvKeyMicrosoftClientID].(string) != "" && currentData[constants.EnvKeyMicrosoftClientSecret].(string) != "" isCurrentMicrosoftLoginEnabled := currentData[constants.EnvKeyMicrosoftClientID] != nil && currentData[constants.EnvKeyMicrosoftClientSecret] != nil && currentData[constants.EnvKeyMicrosoftClientID].(string) != "" && currentData[constants.EnvKeyMicrosoftClientSecret].(string) != ""
isCurrentTwitchLoginEnabled := currentData[constants.EnvKeyTwitchClientID] != nil && currentData[constants.EnvKeyTwitchClientSecret] != nil && currentData[constants.EnvKeyTwitchClientID].(string) != "" && currentData[constants.EnvKeyTwitchClientSecret].(string) != ""
isUpdatedBasicAuthEnabled := !updatedData[constants.EnvKeyDisableBasicAuthentication].(bool) isUpdatedBasicAuthEnabled := !updatedData[constants.EnvKeyDisableBasicAuthentication].(bool)
isUpdatedMobileBasicAuthEnabled := !updatedData[constants.EnvKeyDisableMobileBasicAuthentication].(bool) isUpdatedMobileBasicAuthEnabled := !updatedData[constants.EnvKeyDisableMobileBasicAuthentication].(bool)
@ -45,6 +46,7 @@ func clearSessionIfRequired(currentData, updatedData map[string]interface{}) {
isUpdatedLinkedInLoginEnabled := updatedData[constants.EnvKeyLinkedInClientID] != nil && updatedData[constants.EnvKeyLinkedInClientSecret] != nil && updatedData[constants.EnvKeyLinkedInClientID].(string) != "" && updatedData[constants.EnvKeyLinkedInClientSecret].(string) != "" isUpdatedLinkedInLoginEnabled := updatedData[constants.EnvKeyLinkedInClientID] != nil && updatedData[constants.EnvKeyLinkedInClientSecret] != nil && updatedData[constants.EnvKeyLinkedInClientID].(string) != "" && updatedData[constants.EnvKeyLinkedInClientSecret].(string) != ""
isUpdatedTwitterLoginEnabled := updatedData[constants.EnvKeyTwitterClientID] != nil && updatedData[constants.EnvKeyTwitterClientSecret] != nil && updatedData[constants.EnvKeyTwitterClientID].(string) != "" && updatedData[constants.EnvKeyTwitterClientSecret].(string) != "" isUpdatedTwitterLoginEnabled := updatedData[constants.EnvKeyTwitterClientID] != nil && updatedData[constants.EnvKeyTwitterClientSecret] != nil && updatedData[constants.EnvKeyTwitterClientID].(string) != "" && updatedData[constants.EnvKeyTwitterClientSecret].(string) != ""
isUpdatedMicrosoftLoginEnabled := updatedData[constants.EnvKeyMicrosoftClientID] != nil && updatedData[constants.EnvKeyMicrosoftClientSecret] != nil && updatedData[constants.EnvKeyMicrosoftClientID].(string) != "" && updatedData[constants.EnvKeyMicrosoftClientSecret].(string) != "" isUpdatedMicrosoftLoginEnabled := updatedData[constants.EnvKeyMicrosoftClientID] != nil && updatedData[constants.EnvKeyMicrosoftClientSecret] != nil && updatedData[constants.EnvKeyMicrosoftClientID].(string) != "" && updatedData[constants.EnvKeyMicrosoftClientSecret].(string) != ""
isUpdatedTwitchLoginEnabled := updatedData[constants.EnvKeyTwitchClientID] != nil && updatedData[constants.EnvKeyTwitchClientSecret] != nil && updatedData[constants.EnvKeyTwitchClientID].(string) != "" && updatedData[constants.EnvKeyTwitchClientSecret].(string) != ""
if isCurrentBasicAuthEnabled && !isUpdatedBasicAuthEnabled { if isCurrentBasicAuthEnabled && !isUpdatedBasicAuthEnabled {
memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodBasicAuth) memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodBasicAuth)
@ -85,6 +87,10 @@ func clearSessionIfRequired(currentData, updatedData map[string]interface{}) {
if isCurrentMicrosoftLoginEnabled && !isUpdatedMicrosoftLoginEnabled { if isCurrentMicrosoftLoginEnabled && !isUpdatedMicrosoftLoginEnabled {
memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodMicrosoft) memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodMicrosoft)
} }
if isCurrentTwitchLoginEnabled && !isUpdatedTwitchLoginEnabled {
memorystore.Provider.DeleteSessionForNamespace(constants.AuthRecipeMethodTwitch)
}
} }
// UpdateEnvResolver is a resolver for update config mutation // UpdateEnvResolver is a resolver for update config mutation