diff --git a/server/constants/oauth_info_urls.go b/server/constants/oauth_info_urls.go index 875add5..900a2bf 100644 --- a/server/constants/oauth_info_urls.go +++ b/server/constants/oauth_info_urls.go @@ -8,6 +8,9 @@ const ( FacebookUserInfoURL = "https://graph.facebook.com/me?fields=id,first_name,last_name,name,email,picture&access_token=" // Ref: https://docs.github.com/en/developers/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#3-your-github-app-accesses-the-api-with-the-users-access-token GithubUserInfoURL = "https://api.github.com/user" + // Get github user emails Ref: https://stackoverflow.com/a/35387123 + GithubUserEmails = "https://api/github.com/user/emails" + // Ref: https://docs.microsoft.com/en-us/linkedin/shared/integrations/people/profile-api LinkedInUserInfoURL = "https://api.linkedin.com/v2/me?projection=(id,localizedFirstName,localizedLastName,emailAddress,profilePicture(displayImage~:playableStreams))" LinkedInEmailURL = "https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))" diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index dbe9503..fec93e1 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -143,30 +143,33 @@ type ComplexityRoot struct { } Mutation struct { - AddWebhook func(childComplexity int, params model.AddWebhookRequest) int - AdminLogin func(childComplexity int, params model.AdminLoginInput) int - AdminLogout func(childComplexity int) int - AdminSignup func(childComplexity int, params model.AdminSignupInput) int - DeleteUser func(childComplexity int, params model.DeleteUserInput) int - DeleteWebhook func(childComplexity int, params model.WebhookRequest) int - EnableAccess func(childComplexity int, param model.UpdateAccessInput) int - ForgotPassword func(childComplexity int, params model.ForgotPasswordInput) int - GenerateJwtKeys func(childComplexity int, params model.GenerateJWTKeysInput) int - InviteMembers func(childComplexity int, params model.InviteMemberInput) int - Login func(childComplexity int, params model.LoginInput) int - Logout func(childComplexity int) int - MagicLinkLogin func(childComplexity int, params model.MagicLinkLoginInput) int - ResendVerifyEmail func(childComplexity int, params model.ResendVerifyEmailInput) int - ResetPassword func(childComplexity int, params model.ResetPasswordInput) int - Revoke func(childComplexity int, params model.OAuthRevokeInput) int - RevokeAccess func(childComplexity int, param model.UpdateAccessInput) int - Signup func(childComplexity int, params model.SignUpInput) int - TestEndpoint func(childComplexity int, params model.TestEndpointRequest) int - UpdateEnv func(childComplexity int, params model.UpdateEnvInput) int - UpdateProfile func(childComplexity int, params model.UpdateProfileInput) int - UpdateUser func(childComplexity int, params model.UpdateUserInput) int - UpdateWebhook func(childComplexity int, params model.UpdateWebhookRequest) int - VerifyEmail func(childComplexity int, params model.VerifyEmailInput) int + AddEmailTemplate func(childComplexity int, params model.AddEmailTemplateRequest) int + AddWebhook func(childComplexity int, params model.AddWebhookRequest) int + AdminLogin func(childComplexity int, params model.AdminLoginInput) int + AdminLogout func(childComplexity int) int + AdminSignup func(childComplexity int, params model.AdminSignupInput) int + DeleteEmailTemplate func(childComplexity int, params model.DeleteEmailTemplateRequest) int + DeleteUser func(childComplexity int, params model.DeleteUserInput) int + DeleteWebhook func(childComplexity int, params model.WebhookRequest) int + EnableAccess func(childComplexity int, param model.UpdateAccessInput) int + ForgotPassword func(childComplexity int, params model.ForgotPasswordInput) int + GenerateJwtKeys func(childComplexity int, params model.GenerateJWTKeysInput) int + InviteMembers func(childComplexity int, params model.InviteMemberInput) int + Login func(childComplexity int, params model.LoginInput) int + Logout func(childComplexity int) int + MagicLinkLogin func(childComplexity int, params model.MagicLinkLoginInput) int + ResendVerifyEmail func(childComplexity int, params model.ResendVerifyEmailInput) int + ResetPassword func(childComplexity int, params model.ResetPasswordInput) int + Revoke func(childComplexity int, params model.OAuthRevokeInput) int + RevokeAccess func(childComplexity int, param model.UpdateAccessInput) int + Signup func(childComplexity int, params model.SignUpInput) int + TestEndpoint func(childComplexity int, params model.TestEndpointRequest) int + UpdateEmailTemplate func(childComplexity int, params model.UpdateEmailTemplateRequest) int + UpdateEnv func(childComplexity int, params model.UpdateEnvInput) int + UpdateProfile func(childComplexity int, params model.UpdateProfileInput) int + UpdateUser func(childComplexity int, params model.UpdateUserInput) int + UpdateWebhook func(childComplexity int, params model.UpdateWebhookRequest) int + VerifyEmail func(childComplexity int, params model.VerifyEmailInput) int } Pagination struct { @@ -178,6 +181,7 @@ type ComplexityRoot struct { Query struct { AdminSession func(childComplexity int) int + EmailTemplates func(childComplexity int, params *model.PaginatedInput) int Env func(childComplexity int) int Meta func(childComplexity int) int Profile func(childComplexity int) int @@ -302,6 +306,9 @@ type MutationResolver interface { UpdateWebhook(ctx context.Context, params model.UpdateWebhookRequest) (*model.Response, error) DeleteWebhook(ctx context.Context, params model.WebhookRequest) (*model.Response, error) TestEndpoint(ctx context.Context, params model.TestEndpointRequest) (*model.TestEndpointResponse, error) + AddEmailTemplate(ctx context.Context, params model.AddEmailTemplateRequest) (*model.Response, error) + UpdateEmailTemplate(ctx context.Context, params model.UpdateEmailTemplateRequest) (*model.Response, error) + DeleteEmailTemplate(ctx context.Context, params model.DeleteEmailTemplateRequest) (*model.Response, error) } type QueryResolver interface { Meta(ctx context.Context) (*model.Meta, error) @@ -315,6 +322,7 @@ type QueryResolver interface { Webhook(ctx context.Context, params model.WebhookRequest) (*model.Webhook, error) Webhooks(ctx context.Context, params *model.PaginatedInput) (*model.Webhooks, error) WebhookLogs(ctx context.Context, params *model.ListWebhookLogRequest) (*model.WebhookLogs, error) + EmailTemplates(ctx context.Context, params *model.PaginatedInput) (*model.EmailTemplates, error) } type executableSchema struct { @@ -878,6 +886,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Meta.Version(childComplexity), true + case "Mutation._add_email_template": + if e.complexity.Mutation.AddEmailTemplate == nil { + break + } + + args, err := ec.field_Mutation__add_email_template_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.AddEmailTemplate(childComplexity, args["params"].(model.AddEmailTemplateRequest)), true + case "Mutation._add_webhook": if e.complexity.Mutation.AddWebhook == nil { break @@ -921,6 +941,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.AdminSignup(childComplexity, args["params"].(model.AdminSignupInput)), true + case "Mutation._delete_email_template": + if e.complexity.Mutation.DeleteEmailTemplate == nil { + break + } + + args, err := ec.field_Mutation__delete_email_template_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.DeleteEmailTemplate(childComplexity, args["params"].(model.DeleteEmailTemplateRequest)), true + case "Mutation._delete_user": if e.complexity.Mutation.DeleteUser == nil { break @@ -1096,6 +1128,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.TestEndpoint(childComplexity, args["params"].(model.TestEndpointRequest)), true + case "Mutation._update_email_template": + if e.complexity.Mutation.UpdateEmailTemplate == nil { + break + } + + args, err := ec.field_Mutation__update_email_template_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.UpdateEmailTemplate(childComplexity, args["params"].(model.UpdateEmailTemplateRequest)), true + case "Mutation._update_env": if e.complexity.Mutation.UpdateEnv == nil { break @@ -1191,6 +1235,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.AdminSession(childComplexity), true + case "Query._email_templates": + if e.complexity.Query.EmailTemplates == nil { + break + } + + args, err := ec.field_Query__email_templates_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.EmailTemplates(childComplexity, args["params"].(*model.PaginatedInput)), true + case "Query._env": if e.complexity.Query.Env == nil { break @@ -1883,6 +1939,54 @@ type GenerateJWTKeysResponse { private_key: String } +type Webhook { + id: ID! + event_name: String + endpoint: String + enabled: Boolean + headers: Map + created_at: Int64 + updated_at: Int64 +} + +type Webhooks { + pagination: Pagination! + webhooks: [Webhook!]! +} + +type WebhookLog { + id: ID! + http_status: Int64 + response: String + request: String + webhook_id: ID + created_at: Int64 + updated_at: Int64 +} + +type TestEndpointResponse { + http_status: Int64 + response: Map +} + +type WebhookLogs { + pagination: Pagination! + webhook_logs: [WebhookLog!]! +} + +type EmailTemplate { + id: ID! + event_name: String! + template: String! + created_at: Int64 + updated_at: Int64 +} + +type EmailTemplates { + pagination: Pagination! + EmailTemplates: [EmailTemplate!]! +} + input UpdateEnvInput { ACCESS_TOKEN_EXPIRY_TIME: String ADMIN_SECRET: String @@ -2057,49 +2161,6 @@ input GenerateJWTKeysInput { type: String! } -type Webhook { - id: ID! - event_name: String - endpoint: String - enabled: Boolean - headers: Map - created_at: Int64 - updated_at: Int64 -} - -type Webhooks { - pagination: Pagination! - webhooks: [Webhook!]! -} - -type WebhookLog { - id: ID! - http_status: Int64 - response: String - request: String - webhook_id: ID - created_at: Int64 - updated_at: Int64 -} - -type TestEndpointResponse { - http_status: Int64 - response: Map -} - -type EmailTemplate { - id: ID! - event_name: String! - template: String! - created_at: Int64 - updated_at: Int64 -} - -type EmailTemplates { - pagination: Pagination! - EmailTemplates: [EmailTemplate!]! -} - input ListWebhookLogRequest { pagination: PaginationInput webhook_id: String @@ -2130,9 +2191,19 @@ input TestEndpointRequest { headers: Map } -type WebhookLogs { - pagination: Pagination! - webhook_logs: [WebhookLog!]! +input AddEmailTemplateRequest { + event_name: String! + template: String! +} + +input UpdateEmailTemplateRequest { + id: ID! + event_name: String + template: String +} + +input DeleteEmailTemplateRequest { + id: ID! } type Mutation { @@ -2161,6 +2232,9 @@ type Mutation { _update_webhook(params: UpdateWebhookRequest!): Response! _delete_webhook(params: WebhookRequest!): Response! _test_endpoint(params: TestEndpointRequest!): TestEndpointResponse! + _add_email_template(params: AddEmailTemplateRequest!): Response! + _update_email_template(params: UpdateEmailTemplateRequest!): Response! + _delete_email_template(params: DeleteEmailTemplateRequest!): Response! } type Query { @@ -2176,6 +2250,7 @@ type Query { _webhook(params: WebhookRequest!): Webhook! _webhooks(params: PaginatedInput): Webhooks! _webhook_logs(params: ListWebhookLogRequest): WebhookLogs! + _email_templates(params: PaginatedInput): EmailTemplates! } `, BuiltIn: false}, } @@ -2185,6 +2260,21 @@ var parsedSchema = gqlparser.MustLoadSchema(sources...) // region ***************************** args.gotpl ***************************** +func (ec *executionContext) field_Mutation__add_email_template_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.AddEmailTemplateRequest + if tmp, ok := rawArgs["params"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params")) + arg0, err = ec.unmarshalNAddEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAddEmailTemplateRequest(ctx, tmp) + if err != nil { + return nil, err + } + } + args["params"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation__add_webhook_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -2230,6 +2320,21 @@ func (ec *executionContext) field_Mutation__admin_signup_args(ctx context.Contex return args, nil } +func (ec *executionContext) field_Mutation__delete_email_template_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.DeleteEmailTemplateRequest + if tmp, ok := rawArgs["params"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params")) + arg0, err = ec.unmarshalNDeleteEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐDeleteEmailTemplateRequest(ctx, tmp) + if err != nil { + return nil, err + } + } + args["params"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation__delete_user_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -2335,6 +2440,21 @@ func (ec *executionContext) field_Mutation__test_endpoint_args(ctx context.Conte return args, nil } +func (ec *executionContext) field_Mutation__update_email_template_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.UpdateEmailTemplateRequest + if tmp, ok := rawArgs["params"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params")) + arg0, err = ec.unmarshalNUpdateEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateEmailTemplateRequest(ctx, tmp) + if err != nil { + return nil, err + } + } + args["params"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation__update_env_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -2530,6 +2650,21 @@ func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs return args, nil } +func (ec *executionContext) field_Query__email_templates_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 *model.PaginatedInput + if tmp, ok := rawArgs["params"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params")) + arg0, err = ec.unmarshalOPaginatedInput2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐPaginatedInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["params"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query__users_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -6250,6 +6385,132 @@ func (ec *executionContext) _Mutation__test_endpoint(ctx context.Context, field return ec.marshalNTestEndpointResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐTestEndpointResponse(ctx, field.Selections, res) } +func (ec *executionContext) _Mutation__add_email_template(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Mutation", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Mutation__add_email_template_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().AddEmailTemplate(rctx, args["params"].(model.AddEmailTemplateRequest)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Response) + fc.Result = res + return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res) +} + +func (ec *executionContext) _Mutation__update_email_template(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Mutation", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Mutation__update_email_template_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().UpdateEmailTemplate(rctx, args["params"].(model.UpdateEmailTemplateRequest)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Response) + fc.Result = res + return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res) +} + +func (ec *executionContext) _Mutation__delete_email_template(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Mutation", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Mutation__delete_email_template_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().DeleteEmailTemplate(rctx, args["params"].(model.DeleteEmailTemplateRequest)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Response) + fc.Result = res + return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res) +} + func (ec *executionContext) _Pagination_limit(ctx context.Context, field graphql.CollectedField, obj *model.Pagination) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -6824,6 +7085,48 @@ func (ec *executionContext) _Query__webhook_logs(ctx context.Context, field grap return ec.marshalNWebhookLogs2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐWebhookLogs(ctx, field.Selections, res) } +func (ec *executionContext) _Query__email_templates(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query__email_templates_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().EmailTemplates(rctx, args["params"].(*model.PaginatedInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.EmailTemplates) + fc.Result = res + return ec.marshalNEmailTemplates2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEmailTemplates(ctx, field.Selections, res) +} + func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -9767,6 +10070,37 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co // region **************************** input.gotpl ***************************** +func (ec *executionContext) unmarshalInputAddEmailTemplateRequest(ctx context.Context, obj interface{}) (model.AddEmailTemplateRequest, error) { + var it model.AddEmailTemplateRequest + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "event_name": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("event_name")) + it.EventName, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + case "template": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("template")) + it.Template, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputAddWebhookRequest(ctx context.Context, obj interface{}) (model.AddWebhookRequest, error) { var it model.AddWebhookRequest asMap := map[string]interface{}{} @@ -9860,6 +10194,29 @@ func (ec *executionContext) unmarshalInputAdminSignupInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputDeleteEmailTemplateRequest(ctx context.Context, obj interface{}) (model.DeleteEmailTemplateRequest, error) { + var it model.DeleteEmailTemplateRequest + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "id": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + it.ID, err = ec.unmarshalNID2string(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputDeleteUserInput(ctx context.Context, obj interface{}) (model.DeleteUserInput, error) { var it model.DeleteUserInput asMap := map[string]interface{}{} @@ -10476,6 +10833,45 @@ func (ec *executionContext) unmarshalInputUpdateAccessInput(ctx context.Context, return it, nil } +func (ec *executionContext) unmarshalInputUpdateEmailTemplateRequest(ctx context.Context, obj interface{}) (model.UpdateEmailTemplateRequest, error) { + var it model.UpdateEmailTemplateRequest + asMap := map[string]interface{}{} + for k, v := range obj.(map[string]interface{}) { + asMap[k] = v + } + + for k, v := range asMap { + switch k { + case "id": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("id")) + it.ID, err = ec.unmarshalNID2string(ctx, v) + if err != nil { + return it, err + } + case "event_name": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("event_name")) + it.EventName, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + case "template": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("template")) + it.Template, err = ec.unmarshalOString2ᚖstring(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + func (ec *executionContext) unmarshalInputUpdateEnvInput(ctx context.Context, obj interface{}) (model.UpdateEnvInput, error) { var it model.UpdateEnvInput asMap := map[string]interface{}{} @@ -11705,6 +12101,21 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { invalids++ } + case "_add_email_template": + out.Values[i] = ec._Mutation__add_email_template(ctx, field) + if out.Values[i] == graphql.Null { + invalids++ + } + case "_update_email_template": + out.Values[i] = ec._Mutation__update_email_template(ctx, field) + if out.Values[i] == graphql.Null { + invalids++ + } + case "_delete_email_template": + out.Values[i] = ec._Mutation__delete_email_template(ctx, field) + if out.Values[i] == graphql.Null { + invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -11927,6 +12338,20 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr } return res }) + case "_email_templates": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query__email_templates(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&invalids, 1) + } + return res + }) case "__type": out.Values[i] = ec._Query___type(ctx, field) case "__schema": @@ -12594,6 +13019,11 @@ func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, o // region ***************************** type.gotpl ***************************** +func (ec *executionContext) unmarshalNAddEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAddEmailTemplateRequest(ctx context.Context, v interface{}) (model.AddEmailTemplateRequest, error) { + res, err := ec.unmarshalInputAddEmailTemplateRequest(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) unmarshalNAddWebhookRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐAddWebhookRequest(ctx context.Context, v interface{}) (model.AddWebhookRequest, error) { res, err := ec.unmarshalInputAddWebhookRequest(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -12638,6 +13068,11 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se return res } +func (ec *executionContext) unmarshalNDeleteEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐDeleteEmailTemplateRequest(ctx context.Context, v interface{}) (model.DeleteEmailTemplateRequest, error) { + res, err := ec.unmarshalInputDeleteEmailTemplateRequest(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) unmarshalNDeleteUserInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐDeleteUserInput(ctx context.Context, v interface{}) (model.DeleteUserInput, error) { res, err := ec.unmarshalInputDeleteUserInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -12697,6 +13132,20 @@ func (ec *executionContext) marshalNEmailTemplate2ᚖgithubᚗcomᚋauthorizerde return ec._EmailTemplate(ctx, sel, v) } +func (ec *executionContext) marshalNEmailTemplates2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEmailTemplates(ctx context.Context, sel ast.SelectionSet, v model.EmailTemplates) graphql.Marshaler { + return ec._EmailTemplates(ctx, sel, &v) +} + +func (ec *executionContext) marshalNEmailTemplates2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEmailTemplates(ctx context.Context, sel ast.SelectionSet, v *model.EmailTemplates) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._EmailTemplates(ctx, sel, v) +} + func (ec *executionContext) marshalNEnv2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐEnv(ctx context.Context, sel ast.SelectionSet, v model.Env) graphql.Marshaler { return ec._Env(ctx, sel, &v) } @@ -12913,6 +13362,11 @@ func (ec *executionContext) unmarshalNUpdateAccessInput2githubᚗcomᚋauthorize return res, graphql.ErrorOnPath(ctx, err) } +func (ec *executionContext) unmarshalNUpdateEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateEmailTemplateRequest(ctx context.Context, v interface{}) (model.UpdateEmailTemplateRequest, error) { + res, err := ec.unmarshalInputUpdateEmailTemplateRequest(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) unmarshalNUpdateEnvInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUpdateEnvInput(ctx context.Context, v interface{}) (model.UpdateEnvInput, error) { res, err := ec.unmarshalInputUpdateEnvInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index 30747dd..195f428 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -2,6 +2,11 @@ package model +type AddEmailTemplateRequest struct { + EventName string `json:"event_name"` + Template string `json:"template"` +} + type AddWebhookRequest struct { EventName string `json:"event_name"` Endpoint string `json:"endpoint"` @@ -26,6 +31,10 @@ type AuthResponse struct { User *User `json:"user"` } +type DeleteEmailTemplateRequest struct { + ID string `json:"id"` +} + type DeleteUserInput struct { Email string `json:"email"` } @@ -227,6 +236,12 @@ type UpdateAccessInput struct { UserID string `json:"user_id"` } +type UpdateEmailTemplateRequest struct { + ID string `json:"id"` + EventName *string `json:"event_name"` + Template *string `json:"template"` +} + type UpdateEnvInput struct { AccessTokenExpiryTime *string `json:"ACCESS_TOKEN_EXPIRY_TIME"` AdminSecret *string `json:"ADMIN_SECRET"` diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index 3d02d5b..bd5845a 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -150,6 +150,54 @@ type GenerateJWTKeysResponse { private_key: String } +type Webhook { + id: ID! + event_name: String + endpoint: String + enabled: Boolean + headers: Map + created_at: Int64 + updated_at: Int64 +} + +type Webhooks { + pagination: Pagination! + webhooks: [Webhook!]! +} + +type WebhookLog { + id: ID! + http_status: Int64 + response: String + request: String + webhook_id: ID + created_at: Int64 + updated_at: Int64 +} + +type TestEndpointResponse { + http_status: Int64 + response: Map +} + +type WebhookLogs { + pagination: Pagination! + webhook_logs: [WebhookLog!]! +} + +type EmailTemplate { + id: ID! + event_name: String! + template: String! + created_at: Int64 + updated_at: Int64 +} + +type EmailTemplates { + pagination: Pagination! + EmailTemplates: [EmailTemplate!]! +} + input UpdateEnvInput { ACCESS_TOKEN_EXPIRY_TIME: String ADMIN_SECRET: String @@ -324,49 +372,6 @@ input GenerateJWTKeysInput { type: String! } -type Webhook { - id: ID! - event_name: String - endpoint: String - enabled: Boolean - headers: Map - created_at: Int64 - updated_at: Int64 -} - -type Webhooks { - pagination: Pagination! - webhooks: [Webhook!]! -} - -type WebhookLog { - id: ID! - http_status: Int64 - response: String - request: String - webhook_id: ID - created_at: Int64 - updated_at: Int64 -} - -type TestEndpointResponse { - http_status: Int64 - response: Map -} - -type EmailTemplate { - id: ID! - event_name: String! - template: String! - created_at: Int64 - updated_at: Int64 -} - -type EmailTemplates { - pagination: Pagination! - EmailTemplates: [EmailTemplate!]! -} - input ListWebhookLogRequest { pagination: PaginationInput webhook_id: String @@ -397,9 +402,19 @@ input TestEndpointRequest { headers: Map } -type WebhookLogs { - pagination: Pagination! - webhook_logs: [WebhookLog!]! +input AddEmailTemplateRequest { + event_name: String! + template: String! +} + +input UpdateEmailTemplateRequest { + id: ID! + event_name: String + template: String +} + +input DeleteEmailTemplateRequest { + id: ID! } type Mutation { @@ -428,6 +443,9 @@ type Mutation { _update_webhook(params: UpdateWebhookRequest!): Response! _delete_webhook(params: WebhookRequest!): Response! _test_endpoint(params: TestEndpointRequest!): TestEndpointResponse! + _add_email_template(params: AddEmailTemplateRequest!): Response! + _update_email_template(params: UpdateEmailTemplateRequest!): Response! + _delete_email_template(params: DeleteEmailTemplateRequest!): Response! } type Query { @@ -443,4 +461,5 @@ type Query { _webhook(params: WebhookRequest!): Webhook! _webhooks(params: PaginatedInput): Webhooks! _webhook_logs(params: ListWebhookLogRequest): WebhookLogs! + _email_templates(params: PaginatedInput): EmailTemplates! } diff --git a/server/graph/schema.resolvers.go b/server/graph/schema.resolvers.go index 59398f9..299edca 100644 --- a/server/graph/schema.resolvers.go +++ b/server/graph/schema.resolvers.go @@ -5,6 +5,7 @@ package graph import ( "context" + "fmt" "github.com/authorizerdev/authorizer/server/graph/generated" "github.com/authorizerdev/authorizer/server/graph/model" @@ -107,6 +108,18 @@ func (r *mutationResolver) TestEndpoint(ctx context.Context, params model.TestEn return resolvers.TestEndpointResolver(ctx, params) } +func (r *mutationResolver) AddEmailTemplate(ctx context.Context, params model.AddEmailTemplateRequest) (*model.Response, error) { + panic(fmt.Errorf("not implemented")) +} + +func (r *mutationResolver) UpdateEmailTemplate(ctx context.Context, params model.UpdateEmailTemplateRequest) (*model.Response, error) { + panic(fmt.Errorf("not implemented")) +} + +func (r *mutationResolver) DeleteEmailTemplate(ctx context.Context, params model.DeleteEmailTemplateRequest) (*model.Response, error) { + panic(fmt.Errorf("not implemented")) +} + func (r *queryResolver) Meta(ctx context.Context) (*model.Meta, error) { return resolvers.MetaResolver(ctx) } @@ -151,6 +164,10 @@ func (r *queryResolver) WebhookLogs(ctx context.Context, params *model.ListWebho return resolvers.WebhookLogsResolver(ctx, params) } +func (r *queryResolver) EmailTemplates(ctx context.Context, params *model.PaginatedInput) (*model.EmailTemplates, error) { + panic(fmt.Errorf("not implemented")) +} + // Mutation returns generated.MutationResolver implementation. func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} } diff --git a/server/handlers/oauth_callback.go b/server/handlers/oauth_callback.go index a19fa46..7e316a3 100644 --- a/server/handlers/oauth_callback.go +++ b/server/handlers/oauth_callback.go @@ -320,12 +320,60 @@ func processGithubUserInfo(code string) (models.User, error) { } picture := userRawData["avatar_url"] + email := userRawData["email"] + + if email == "" { + type GithubUserEmails struct { + Email string `json:"email"` + Primary bool `json:"primary"` + } + + // fetch using /users/email endpoint + req, err := http.NewRequest("GET", constants.GithubUserEmails, nil) + if err != nil { + log.Debug("Failed to create github emails request: ", err) + return user, fmt.Errorf("error creating github user info request: %s", err.Error()) + } + req.Header = http.Header{ + "Authorization": []string{fmt.Sprintf("token %s", oauth2Token.AccessToken)}, + } + + response, err := client.Do(req) + if err != nil { + log.Debug("Failed to request github user email: ", err) + return user, err + } + + defer response.Body.Close() + body, err := ioutil.ReadAll(response.Body) + if err != nil { + log.Debug("Failed to read github user email response body: ", err) + return user, fmt.Errorf("failed to read github response body: %s", err.Error()) + } + if response.StatusCode >= 400 { + log.Debug("Failed to request github user email: ", string(body)) + return user, fmt.Errorf("failed to request github user info: %s", string(body)) + } + + emailData := []GithubUserEmails{} + err = json.Unmarshal(body, &emailData) + if err != nil { + log.Debug("Failed to parse github user email: ", err) + } + + for _, userEmail := range emailData { + email = userEmail.Email + if userEmail.Primary { + break + } + } + } user = models.User{ GivenName: &firstName, FamilyName: &lastName, Picture: &picture, - Email: userRawData["email"], + Email: email, } return user, nil diff --git a/server/resolvers/add_email_template.go b/server/resolvers/add_email_template.go new file mode 100644 index 0000000..91fea07 --- /dev/null +++ b/server/resolvers/add_email_template.go @@ -0,0 +1 @@ +package resolvers diff --git a/server/resolvers/delete_email_template.go b/server/resolvers/delete_email_template.go new file mode 100644 index 0000000..91fea07 --- /dev/null +++ b/server/resolvers/delete_email_template.go @@ -0,0 +1 @@ +package resolvers diff --git a/server/resolvers/email_templates.go b/server/resolvers/email_templates.go new file mode 100644 index 0000000..91fea07 --- /dev/null +++ b/server/resolvers/email_templates.go @@ -0,0 +1 @@ +package resolvers diff --git a/server/resolvers/update_email_template.go b/server/resolvers/update_email_template.go new file mode 100644 index 0000000..91fea07 --- /dev/null +++ b/server/resolvers/update_email_template.go @@ -0,0 +1 @@ +package resolvers