Merge branch 'main' of dev.discours.io:authorizer
Some checks failed
deploy / deploy (push) Failing after 5s
Some checks failed
deploy / deploy (push) Failing after 5s
This commit is contained in:
commit
4b172892e5
15
.github/CONTRIBUTING.md
vendored
15
.github/CONTRIBUTING.md
vendored
|
@ -229,6 +229,21 @@ mutation Logout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutation CreateUser {
|
||||||
|
_create_user(
|
||||||
|
params: {
|
||||||
|
email: "test@domain.com",
|
||||||
|
password: "<bcrypt-hashed-password>",
|
||||||
|
nickname: "test",
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
id
|
||||||
|
email
|
||||||
|
roles
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
mutation UpdateUser {
|
mutation UpdateUser {
|
||||||
_update_user(
|
_update_user(
|
||||||
params: {
|
params: {
|
||||||
|
|
|
@ -113,6 +113,13 @@ const EditUserModal = ({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
position: 'top-right',
|
position: 'top-right',
|
||||||
});
|
});
|
||||||
|
} else if (res.data?._create_user?.id) {
|
||||||
|
toast({
|
||||||
|
title: 'User created successfully',
|
||||||
|
isClosable: true,
|
||||||
|
status: 'success',
|
||||||
|
position: 'top-right',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
onClose();
|
onClose();
|
||||||
updateUserList();
|
updateUserList();
|
||||||
|
|
|
@ -38,6 +38,14 @@ export const UpdateUser = `
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const CreateUser = `
|
||||||
|
mutation createUser($params: CreateUserInput!) {
|
||||||
|
_create_user(params: $params) {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
export const DeleteUser = `
|
export const DeleteUser = `
|
||||||
mutation deleteUser($params: DeleteUserInput!) {
|
mutation deleteUser($params: DeleteUserInput!) {
|
||||||
_delete_user(params: $params) {
|
_delete_user(params: $params) {
|
||||||
|
|
|
@ -189,6 +189,13 @@ export default function Users() {
|
||||||
status: 'success',
|
status: 'success',
|
||||||
position: 'top-right',
|
position: 'top-right',
|
||||||
});
|
});
|
||||||
|
} else if (res.data?._create_user?.id) {
|
||||||
|
toast({
|
||||||
|
title: 'User verification successful',
|
||||||
|
isClosable: true,
|
||||||
|
status: 'success',
|
||||||
|
position: 'top-right',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
updateUserList();
|
updateUserList();
|
||||||
};
|
};
|
||||||
|
@ -272,6 +279,17 @@ export default function Users() {
|
||||||
});
|
});
|
||||||
updateUserList();
|
updateUserList();
|
||||||
return;
|
return;
|
||||||
|
} else if (res.data?._create_user?.id) {
|
||||||
|
toast({
|
||||||
|
title: `Multi factor authentication ${
|
||||||
|
user.is_multi_factor_auth_enabled ? 'disabled' : 'enabled'
|
||||||
|
} for user`,
|
||||||
|
isClosable: true,
|
||||||
|
status: 'success',
|
||||||
|
position: 'top-right',
|
||||||
|
});
|
||||||
|
updateUserList();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
toast({
|
toast({
|
||||||
title: 'Multi factor authentication update failed for user',
|
title: 'Multi factor authentication update failed for user',
|
||||||
|
|
|
@ -183,6 +183,7 @@ type ComplexityRoot struct {
|
||||||
AdminLogin func(childComplexity int, params model.AdminLoginInput) int
|
AdminLogin func(childComplexity int, params model.AdminLoginInput) int
|
||||||
AdminLogout func(childComplexity int) int
|
AdminLogout func(childComplexity int) int
|
||||||
AdminSignup func(childComplexity int, params model.AdminSignupInput) int
|
AdminSignup func(childComplexity int, params model.AdminSignupInput) int
|
||||||
|
CreateUser func(childComplexity int, params model.CreateUserInput) int
|
||||||
DeactivateAccount func(childComplexity int) int
|
DeactivateAccount func(childComplexity int) int
|
||||||
DeleteEmailTemplate func(childComplexity int, params model.DeleteEmailTemplateRequest) int
|
DeleteEmailTemplate func(childComplexity int, params model.DeleteEmailTemplateRequest) int
|
||||||
DeleteUser func(childComplexity int, params model.DeleteUserInput) int
|
DeleteUser func(childComplexity int, params model.DeleteUserInput) int
|
||||||
|
@ -357,6 +358,7 @@ type MutationResolver interface {
|
||||||
VerifyOtp(ctx context.Context, params model.VerifyOTPRequest) (*model.AuthResponse, error)
|
VerifyOtp(ctx context.Context, params model.VerifyOTPRequest) (*model.AuthResponse, error)
|
||||||
ResendOtp(ctx context.Context, params model.ResendOTPRequest) (*model.Response, error)
|
ResendOtp(ctx context.Context, params model.ResendOTPRequest) (*model.Response, error)
|
||||||
DeactivateAccount(ctx context.Context) (*model.Response, error)
|
DeactivateAccount(ctx context.Context) (*model.Response, error)
|
||||||
|
CreateUser(ctx context.Context, params model.CreateUserInput) (*model.User, error)
|
||||||
DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error)
|
DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error)
|
||||||
UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error)
|
UpdateUser(ctx context.Context, params model.UpdateUserInput) (*model.User, error)
|
||||||
AdminSignup(ctx context.Context, params model.AdminSignupInput) (*model.Response, error)
|
AdminSignup(ctx context.Context, params model.AdminSignupInput) (*model.Response, error)
|
||||||
|
@ -1215,6 +1217,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Mutation.AdminSignup(childComplexity, args["params"].(model.AdminSignupInput)), true
|
return e.complexity.Mutation.AdminSignup(childComplexity, args["params"].(model.AdminSignupInput)), true
|
||||||
|
|
||||||
|
case "Mutation._create_user":
|
||||||
|
if e.complexity.Mutation.CreateUser == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
args, err := ec.field_Mutation__create_user_args(context.TODO(), rawArgs)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Mutation.CreateUser(childComplexity, args["params"].(model.CreateUserInput)), true
|
||||||
|
|
||||||
case "Mutation.deactivate_account":
|
case "Mutation.deactivate_account":
|
||||||
if e.complexity.Mutation.DeactivateAccount == nil {
|
if e.complexity.Mutation.DeactivateAccount == nil {
|
||||||
break
|
break
|
||||||
|
@ -2172,6 +2186,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
|
||||||
ec.unmarshalInputAddWebhookRequest,
|
ec.unmarshalInputAddWebhookRequest,
|
||||||
ec.unmarshalInputAdminLoginInput,
|
ec.unmarshalInputAdminLoginInput,
|
||||||
ec.unmarshalInputAdminSignupInput,
|
ec.unmarshalInputAdminSignupInput,
|
||||||
|
ec.unmarshalInputCreateUserInput,
|
||||||
ec.unmarshalInputDeleteEmailTemplateRequest,
|
ec.unmarshalInputDeleteEmailTemplateRequest,
|
||||||
ec.unmarshalInputDeleteUserInput,
|
ec.unmarshalInputDeleteUserInput,
|
||||||
ec.unmarshalInputForgotPasswordInput,
|
ec.unmarshalInputForgotPasswordInput,
|
||||||
|
@ -2726,6 +2741,22 @@ input UpdateProfileInput {
|
||||||
app_data: Map
|
app_data: Map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input CreateUserInput {
|
||||||
|
email: String
|
||||||
|
email_verified: Boolean
|
||||||
|
email_verified_at: Int64
|
||||||
|
password: String
|
||||||
|
given_name: String
|
||||||
|
family_name: String
|
||||||
|
middle_name: String
|
||||||
|
nickname: String
|
||||||
|
phone_number: String
|
||||||
|
picture: String
|
||||||
|
created_at: Int64
|
||||||
|
updated_at: Int64
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
input UpdateUserInput {
|
input UpdateUserInput {
|
||||||
id: ID!
|
id: ID!
|
||||||
email: String
|
email: String
|
||||||
|
@ -2910,6 +2941,7 @@ type Mutation {
|
||||||
resend_otp(params: ResendOTPRequest!): Response!
|
resend_otp(params: ResendOTPRequest!): Response!
|
||||||
deactivate_account: Response!
|
deactivate_account: Response!
|
||||||
# admin only apis
|
# admin only apis
|
||||||
|
_create_user(params: CreateUserInput!): User!
|
||||||
_delete_user(params: DeleteUserInput!): Response!
|
_delete_user(params: DeleteUserInput!): Response!
|
||||||
_update_user(params: UpdateUserInput!): User!
|
_update_user(params: UpdateUserInput!): User!
|
||||||
_admin_signup(params: AdminSignupInput!): Response!
|
_admin_signup(params: AdminSignupInput!): Response!
|
||||||
|
@ -3014,6 +3046,21 @@ func (ec *executionContext) field_Mutation__admin_signup_args(ctx context.Contex
|
||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) field_Mutation__create_user_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
|
var err error
|
||||||
|
args := map[string]interface{}{}
|
||||||
|
var arg0 model.CreateUserInput
|
||||||
|
if tmp, ok := rawArgs["params"]; ok {
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
|
||||||
|
arg0, err = ec.unmarshalNCreateUserInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐCreateUserInput(ctx, tmp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args["params"] = arg0
|
||||||
|
return args, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) field_Mutation__delete_email_template_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
func (ec *executionContext) field_Mutation__delete_email_template_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
var err error
|
var err error
|
||||||
args := map[string]interface{}{}
|
args := map[string]interface{}{}
|
||||||
|
@ -9213,6 +9260,103 @@ func (ec *executionContext) fieldContext_Mutation_deactivate_account(ctx context
|
||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Mutation__create_user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
|
fc, err := ec.fieldContext_Mutation__create_user(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 ec.resolvers.Mutation().CreateUser(rctx, fc.Args["params"].(model.CreateUserInput))
|
||||||
|
})
|
||||||
|
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.User)
|
||||||
|
fc.Result = res
|
||||||
|
return ec.marshalNUser2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐUser(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) fieldContext_Mutation__create_user(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
fc = &graphql.FieldContext{
|
||||||
|
Object: "Mutation",
|
||||||
|
Field: field,
|
||||||
|
IsMethod: true,
|
||||||
|
IsResolver: true,
|
||||||
|
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
switch field.Name {
|
||||||
|
case "id":
|
||||||
|
return ec.fieldContext_User_id(ctx, field)
|
||||||
|
case "email":
|
||||||
|
return ec.fieldContext_User_email(ctx, field)
|
||||||
|
case "email_verified":
|
||||||
|
return ec.fieldContext_User_email_verified(ctx, field)
|
||||||
|
case "signup_methods":
|
||||||
|
return ec.fieldContext_User_signup_methods(ctx, field)
|
||||||
|
case "given_name":
|
||||||
|
return ec.fieldContext_User_given_name(ctx, field)
|
||||||
|
case "family_name":
|
||||||
|
return ec.fieldContext_User_family_name(ctx, field)
|
||||||
|
case "middle_name":
|
||||||
|
return ec.fieldContext_User_middle_name(ctx, field)
|
||||||
|
case "nickname":
|
||||||
|
return ec.fieldContext_User_nickname(ctx, field)
|
||||||
|
case "preferred_username":
|
||||||
|
return ec.fieldContext_User_preferred_username(ctx, field)
|
||||||
|
case "gender":
|
||||||
|
return ec.fieldContext_User_gender(ctx, field)
|
||||||
|
case "birthdate":
|
||||||
|
return ec.fieldContext_User_birthdate(ctx, field)
|
||||||
|
case "phone_number":
|
||||||
|
return ec.fieldContext_User_phone_number(ctx, field)
|
||||||
|
case "phone_number_verified":
|
||||||
|
return ec.fieldContext_User_phone_number_verified(ctx, field)
|
||||||
|
case "picture":
|
||||||
|
return ec.fieldContext_User_picture(ctx, field)
|
||||||
|
case "roles":
|
||||||
|
return ec.fieldContext_User_roles(ctx, field)
|
||||||
|
case "created_at":
|
||||||
|
return ec.fieldContext_User_created_at(ctx, field)
|
||||||
|
case "updated_at":
|
||||||
|
return ec.fieldContext_User_updated_at(ctx, field)
|
||||||
|
case "revoked_timestamp":
|
||||||
|
return ec.fieldContext_User_revoked_timestamp(ctx, field)
|
||||||
|
case "is_multi_factor_auth_enabled":
|
||||||
|
return ec.fieldContext_User_is_multi_factor_auth_enabled(ctx, field)
|
||||||
|
case "app_data":
|
||||||
|
return ec.fieldContext_User_app_data(ctx, field)
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("no field named %q was found under type User", field.Name)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
err = ec.Recover(ctx, r)
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
ctx = graphql.WithFieldContext(ctx, fc)
|
||||||
|
if fc.Args, err = ec.field_Mutation__create_user_args(ctx, field.ArgumentMap(ec.Variables)); err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return fc, err
|
||||||
|
}
|
||||||
|
return fc, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Mutation__delete_user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Mutation__delete_user(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
fc, err := ec.fieldContext_Mutation__delete_user(ctx, field)
|
fc, err := ec.fieldContext_Mutation__delete_user(ctx, field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -16485,6 +16629,134 @@ func (ec *executionContext) unmarshalInputAdminSignupInput(ctx context.Context,
|
||||||
return it, nil
|
return it, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalInputCreateUserInput(ctx context.Context, obj interface{}) (model.CreateUserInput, error) {
|
||||||
|
var it model.CreateUserInput
|
||||||
|
asMap := map[string]interface{}{}
|
||||||
|
for k, v := range obj.(map[string]interface{}) {
|
||||||
|
asMap[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldsInOrder := [...]string{"email", "email_verified", "email_verified_at", "password", "given_name", "family_name", "middle_name", "nickname", "phone_number", "picture", "created_at", "updated_at"}
|
||||||
|
for _, k := range fieldsInOrder {
|
||||||
|
v, ok := asMap[k]
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch k {
|
||||||
|
case "email":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email"))
|
||||||
|
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.Email = data
|
||||||
|
case "email_verified":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email_verified"))
|
||||||
|
data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.EmailVerified = data
|
||||||
|
case "email_verified_at":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email_verified_at"))
|
||||||
|
data, err := ec.unmarshalOInt642ᚖint64(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.EmailVerifiedAt = data
|
||||||
|
case "password":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("password"))
|
||||||
|
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.Password = data
|
||||||
|
case "given_name":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("given_name"))
|
||||||
|
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.GivenName = data
|
||||||
|
case "family_name":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("family_name"))
|
||||||
|
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.FamilyName = data
|
||||||
|
case "middle_name":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("middle_name"))
|
||||||
|
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.MiddleName = data
|
||||||
|
case "nickname":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("nickname"))
|
||||||
|
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.Nickname = data
|
||||||
|
case "phone_number":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("phone_number"))
|
||||||
|
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.PhoneNumber = data
|
||||||
|
case "picture":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("picture"))
|
||||||
|
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.Picture = data
|
||||||
|
case "created_at":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("created_at"))
|
||||||
|
data, err := ec.unmarshalOInt642ᚖint64(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.CreatedAt = data
|
||||||
|
case "updated_at":
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("updated_at"))
|
||||||
|
data, err := ec.unmarshalOInt642ᚖint64(ctx, v)
|
||||||
|
if err != nil {
|
||||||
|
return it, err
|
||||||
|
}
|
||||||
|
it.UpdatedAt = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return it, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalInputDeleteEmailTemplateRequest(ctx context.Context, obj interface{}) (model.DeleteEmailTemplateRequest, error) {
|
func (ec *executionContext) unmarshalInputDeleteEmailTemplateRequest(ctx context.Context, obj interface{}) (model.DeleteEmailTemplateRequest, error) {
|
||||||
var it model.DeleteEmailTemplateRequest
|
var it model.DeleteEmailTemplateRequest
|
||||||
asMap := map[string]interface{}{}
|
asMap := map[string]interface{}{}
|
||||||
|
@ -19553,6 +19825,13 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
out.Invalids++
|
||||||
}
|
}
|
||||||
|
case "_create_user":
|
||||||
|
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
|
return ec._Mutation__create_user(ctx, field)
|
||||||
|
})
|
||||||
|
if out.Values[i] == graphql.Null {
|
||||||
|
out.Invalids++
|
||||||
|
}
|
||||||
case "_delete_user":
|
case "_delete_user":
|
||||||
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) {
|
||||||
return ec._Mutation__delete_user(ctx, field)
|
return ec._Mutation__delete_user(ctx, field)
|
||||||
|
@ -21126,6 +21405,11 @@ func (ec *executionContext) marshalNBoolean2bool(ctx context.Context, sel ast.Se
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) unmarshalNCreateUserInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐCreateUserInput(ctx context.Context, v interface{}) (model.CreateUserInput, error) {
|
||||||
|
res, err := ec.unmarshalInputCreateUserInput(ctx, v)
|
||||||
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) unmarshalNDeleteEmailTemplateRequest2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐDeleteEmailTemplateRequest(ctx context.Context, v interface{}) (model.DeleteEmailTemplateRequest, error) {
|
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)
|
res, err := ec.unmarshalInputDeleteEmailTemplateRequest(ctx, v)
|
||||||
return res, graphql.ErrorOnPath(ctx, err)
|
return res, graphql.ErrorOnPath(ctx, err)
|
||||||
|
|
1
server/graph/mod.go
Normal file
1
server/graph/mod.go
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package graph
|
1
server/graph/model/mod.go
Normal file
1
server/graph/model/mod.go
Normal file
|
@ -0,0 +1 @@
|
||||||
|
package model
|
|
@ -40,6 +40,21 @@ type AuthResponse struct {
|
||||||
AuthenticatorRecoveryCodes []*string `json:"authenticator_recovery_codes,omitempty"`
|
AuthenticatorRecoveryCodes []*string `json:"authenticator_recovery_codes,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CreateUserInput struct {
|
||||||
|
Email *string `json:"email,omitempty"`
|
||||||
|
EmailVerified *bool `json:"email_verified,omitempty"`
|
||||||
|
EmailVerifiedAt *int64 `json:"email_verified_at,omitempty"`
|
||||||
|
Password *string `json:"password,omitempty"`
|
||||||
|
GivenName *string `json:"given_name,omitempty"`
|
||||||
|
FamilyName *string `json:"family_name,omitempty"`
|
||||||
|
MiddleName *string `json:"middle_name,omitempty"`
|
||||||
|
Nickname *string `json:"nickname,omitempty"`
|
||||||
|
PhoneNumber *string `json:"phone_number,omitempty"`
|
||||||
|
Picture *string `json:"picture,omitempty"`
|
||||||
|
CreatedAt *int64 `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt *int64 `json:"updated_at,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type DeleteEmailTemplateRequest struct {
|
type DeleteEmailTemplateRequest struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -424,6 +424,22 @@ input UpdateProfileInput {
|
||||||
app_data: Map
|
app_data: Map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input CreateUserInput {
|
||||||
|
email: String
|
||||||
|
email_verified: Boolean
|
||||||
|
email_verified_at: Int64
|
||||||
|
password: String
|
||||||
|
given_name: String
|
||||||
|
family_name: String
|
||||||
|
middle_name: String
|
||||||
|
nickname: String
|
||||||
|
phone_number: String
|
||||||
|
picture: String
|
||||||
|
created_at: Int64
|
||||||
|
updated_at: Int64
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
input UpdateUserInput {
|
input UpdateUserInput {
|
||||||
id: ID!
|
id: ID!
|
||||||
email: String
|
email: String
|
||||||
|
@ -608,6 +624,7 @@ type Mutation {
|
||||||
resend_otp(params: ResendOTPRequest!): Response!
|
resend_otp(params: ResendOTPRequest!): Response!
|
||||||
deactivate_account: Response!
|
deactivate_account: Response!
|
||||||
# admin only apis
|
# admin only apis
|
||||||
|
_create_user(params: CreateUserInput!): User!
|
||||||
_delete_user(params: DeleteUserInput!): Response!
|
_delete_user(params: DeleteUserInput!): Response!
|
||||||
_update_user(params: UpdateUserInput!): User!
|
_update_user(params: UpdateUserInput!): User!
|
||||||
_admin_signup(params: AdminSignupInput!): Response!
|
_admin_signup(params: AdminSignupInput!): Response!
|
||||||
|
|
|
@ -87,6 +87,11 @@ func (r *mutationResolver) DeactivateAccount(ctx context.Context) (*model.Respon
|
||||||
return resolvers.DeactivateAccountResolver(ctx)
|
return resolvers.DeactivateAccountResolver(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateUser is the resolver for the _create_user field.
|
||||||
|
func (r *mutationResolver) CreateUser(ctx context.Context, params model.CreateUserInput) (*model.User, error) {
|
||||||
|
return resolvers.CreateUserResolver(ctx, params)
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteUser is the resolver for the _delete_user field.
|
// DeleteUser is the resolver for the _delete_user field.
|
||||||
func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
|
func (r *mutationResolver) DeleteUser(ctx context.Context, params model.DeleteUserInput) (*model.Response, error) {
|
||||||
return resolvers.DeleteUserResolver(ctx, params)
|
return resolvers.DeleteUserResolver(ctx, params)
|
||||||
|
|
147
server/resolvers/create_user.go
Normal file
147
server/resolvers/create_user.go
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
package resolvers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
|
"github.com/authorizerdev/authorizer/server/constants"
|
||||||
|
"github.com/authorizerdev/authorizer/server/db"
|
||||||
|
"github.com/authorizerdev/authorizer/server/db/models"
|
||||||
|
"github.com/authorizerdev/authorizer/server/email"
|
||||||
|
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||||
|
"github.com/authorizerdev/authorizer/server/parsers"
|
||||||
|
"github.com/authorizerdev/authorizer/server/refs"
|
||||||
|
"github.com/authorizerdev/authorizer/server/token"
|
||||||
|
"github.com/authorizerdev/authorizer/server/utils"
|
||||||
|
"github.com/authorizerdev/authorizer/server/validators"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateUserResolver is a resolver for create user mutation
|
||||||
|
// This is admin only mutation
|
||||||
|
func CreateUserResolver(ctx context.Context, params model.CreateUserInput) (*model.User, error) {
|
||||||
|
var res *model.User
|
||||||
|
|
||||||
|
gc, err := utils.GinContextFromContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to get GinContext: ", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !token.IsSuperAdmin(gc) {
|
||||||
|
log.Debug("Not logged in as super admin")
|
||||||
|
return res, fmt.Errorf("unauthorized")
|
||||||
|
}
|
||||||
|
|
||||||
|
log := log.New()
|
||||||
|
|
||||||
|
if params.PhoneNumber != nil {
|
||||||
|
// verify if phone number is unique
|
||||||
|
if _, err := db.Provider.GetUserByPhoneNumber(ctx, strings.TrimSpace(refs.StringValue(params.PhoneNumber))); err == nil {
|
||||||
|
log.Debug("user with given phone number already exists")
|
||||||
|
return nil, errors.New("user with given phone number already exists")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.EmailVerified != nil {
|
||||||
|
if *params.EmailVerified {
|
||||||
|
now := time.Now().Unix()
|
||||||
|
params.EmailVerifiedAt = &now
|
||||||
|
} else {
|
||||||
|
params.EmailVerifiedAt = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if params.Email != nil {
|
||||||
|
// check if valid email
|
||||||
|
if !validators.IsValidEmail(*params.Email) {
|
||||||
|
log.Debug("Invalid email: ", *params.Email)
|
||||||
|
return res, fmt.Errorf("invalid email address")
|
||||||
|
}
|
||||||
|
newEmail := strings.ToLower(*params.Email)
|
||||||
|
// check if user with new email exists
|
||||||
|
_, err = db.Provider.GetUserByEmail(ctx, newEmail)
|
||||||
|
// err = nil means user exists
|
||||||
|
if err == nil {
|
||||||
|
log.Debug("User with email already exists: ", newEmail)
|
||||||
|
return res, fmt.Errorf("user with this email address already exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname := parsers.GetHost(gc)
|
||||||
|
params.Email = &newEmail
|
||||||
|
params.EmailVerifiedAt = nil
|
||||||
|
// insert verification request
|
||||||
|
_, nonceHash, err := utils.GenerateNonce()
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to generate nonce: ", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
verificationType := constants.VerificationTypeUpdateEmail
|
||||||
|
redirectURL := parsers.GetAppURL(gc)
|
||||||
|
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to create verification token: ", err)
|
||||||
|
}
|
||||||
|
_, err = db.Provider.AddVerificationRequest(ctx, &models.VerificationRequest{
|
||||||
|
Token: verificationToken,
|
||||||
|
Identifier: verificationType,
|
||||||
|
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
||||||
|
Email: newEmail,
|
||||||
|
Nonce: nonceHash,
|
||||||
|
RedirectURI: redirectURL,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to add verification request: ", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// exec it as go routine so that we can reduce the api latency
|
||||||
|
go email.SendEmail([]string{*params.Email}, constants.VerificationTypeBasicAuthSignup, map[string]interface{}{
|
||||||
|
"user": params,
|
||||||
|
"organization": utils.GetOrganization(),
|
||||||
|
"verification_url": utils.GetEmailVerificationURL(verificationToken, hostname, redirectURL),
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// json-typed model to store in database
|
||||||
|
userdata := models.User{
|
||||||
|
Email: *params.Email,
|
||||||
|
EmailVerifiedAt: params.EmailVerifiedAt,
|
||||||
|
CreatedAt: *params.CreatedAt,
|
||||||
|
UpdatedAt: *params.UpdatedAt,
|
||||||
|
Password: params.Password,
|
||||||
|
GivenName: params.GivenName,
|
||||||
|
FamilyName: params.FamilyName,
|
||||||
|
MiddleName: params.MiddleName,
|
||||||
|
Nickname: params.Nickname, // slug
|
||||||
|
PhoneNumber: params.PhoneNumber,
|
||||||
|
Picture: params.Picture,
|
||||||
|
}
|
||||||
|
|
||||||
|
var user *models.User
|
||||||
|
user, err = db.Provider.AddUser(ctx, &userdata)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Debug("Failed to update user: ", err)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
createdAt := user.CreatedAt
|
||||||
|
updatedAt := user.UpdatedAt
|
||||||
|
res = &model.User{
|
||||||
|
ID: user.ID,
|
||||||
|
Email: user.Email,
|
||||||
|
Picture: user.Picture,
|
||||||
|
GivenName: user.GivenName,
|
||||||
|
FamilyName: user.FamilyName,
|
||||||
|
Roles: strings.Split(user.Roles, ","),
|
||||||
|
CreatedAt: &createdAt,
|
||||||
|
UpdatedAt: &updatedAt,
|
||||||
|
}
|
||||||
|
return res, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user