feat: add resolver for inviting members
This commit is contained in:
parent
1b387f7564
commit
9a19552f72
|
@ -1,6 +1,7 @@
|
|||
import React, { useEffect, lazy, Suspense } from 'react';
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
import { useAuthorizer } from '@authorizerdev/authorizer-react';
|
||||
import SetupPassword from './pages/setup-password';
|
||||
|
||||
const ResetPassword = lazy(() => import('./pages/rest-password'));
|
||||
const Login = lazy(() => import('./pages/login'));
|
||||
|
@ -60,6 +61,9 @@ export default function Root({
|
|||
<Route path="/app/reset-password">
|
||||
<ResetPassword />
|
||||
</Route>
|
||||
<Route path="/app/setup-password">
|
||||
<SetupPassword />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Suspense>
|
||||
);
|
||||
|
|
12
app/src/pages/setup-password.tsx
Normal file
12
app/src/pages/setup-password.tsx
Normal file
|
@ -0,0 +1,12 @@
|
|||
import React, { Fragment } from 'react';
|
||||
import { AuthorizerResetPassword } from '@authorizerdev/authorizer-react';
|
||||
|
||||
export default function SetupPassword() {
|
||||
return (
|
||||
<Fragment>
|
||||
<h1 style={{ textAlign: 'center' }}>Setup new Password</h1>
|
||||
<br />
|
||||
<AuthorizerResetPassword />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
113
server/email/invite_email.go
Normal file
113
server/email/invite_email.go
Normal file
|
@ -0,0 +1,113 @@
|
|||
package email
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
"github.com/authorizerdev/authorizer/server/envstore"
|
||||
)
|
||||
|
||||
// InviteEmail to send invite email
|
||||
func InviteEmail(toEmail, token, url string) error {
|
||||
// The receiver needs to be in slice as the receive supports multiple receiver
|
||||
Receiver := []string{toEmail}
|
||||
|
||||
Subject := "Please accept the invitation"
|
||||
message := `
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="width=device-width, initial-scale=1" name="viewport">
|
||||
<meta name="x-apple-disable-message-reformatting">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta content="telephone=no" name="format-detection">
|
||||
<title></title>
|
||||
<!--[if (mso 16)]>
|
||||
<style type="text/css">
|
||||
a {}
|
||||
</style>
|
||||
<![endif]-->
|
||||
<!--[if gte mso 9]><style>sup { font-size: 100%% !important; }</style><![endif]-->
|
||||
<!--[if gte mso 9]>
|
||||
<xml>
|
||||
<o:OfficeDocumentSettings>
|
||||
<o:AllowPNG></o:AllowPNG>
|
||||
<o:PixelsPerInch>96</o:PixelsPerInch>
|
||||
</o:OfficeDocumentSettings>
|
||||
</xml>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body style="font-family: sans-serif;">
|
||||
<div class="es-wrapper-color">
|
||||
<!--[if gte mso 9]>
|
||||
<v:background xmlns:v="urn:schemas-microsoft-com:vml" fill="t">
|
||||
<v:fill type="tile" color="#ffffff"></v:fill>
|
||||
</v:background>
|
||||
<![endif]-->
|
||||
<table class="es-wrapper" width="100%%" cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="esd-email-paddings" valign="top">
|
||||
<table class="es-content esd-footer-popover" cellspacing="0" cellpadding="0" align="center">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="esd-stripe" align="center">
|
||||
<table class="es-content-body" style="border-left:1px solid transparent;border-right:1px solid transparent;border-top:1px solid transparent;border-bottom:1px solid transparent;padding:20px 0px;" width="600" cellspacing="0" cellpadding="0" bgcolor="#ffffff" align="center">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="esd-structure es-p20t es-p40b es-p40r es-p40l" esd-custom-block-id="8537" align="left">
|
||||
<table width="100%%" cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="esd-container-frame" width="518" align="left">
|
||||
<table width="100%%" cellspacing="0" cellpadding="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="esd-block-image es-m-txt-c es-p5b" style="font-size:0;padding:10px" align="center"><a target="_blank" clicktracking="off"><img src="{{.org_logo}}" alt="icon" style="display: block;" title="icon" width="30"></a></td>
|
||||
</tr>
|
||||
|
||||
<tr style="background: rgb(249,250,251);padding: 10px;margin-bottom:10px;border-radius:5px;">
|
||||
<td class="esd-block-text es-m-txt-c es-p15t" align="center" style="padding:10px;padding-bottom:30px;">
|
||||
<p>Hi there 👋</p>
|
||||
<p>Join us! You are invited to sign-up for <b>{{.org_name}}</b>. Please accept the invitation by clicking the clicking the button below.</p> <br/>
|
||||
<a
|
||||
clicktracking="off" href="{{.verification_url}}" class="es-button" target="_blank" style="text-decoration: none;padding:10px 15px;background-color: rgba(59,130,246,1);color: #fff;font-size: 1em;border-radius:5px;">Get Started</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div style="position: absolute; left: -9999px; top: -9999px; margin: 0px;"></div>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
data := make(map[string]interface{}, 3)
|
||||
data["org_logo"] = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationLogo)
|
||||
data["org_name"] = envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyOrganizationName)
|
||||
data["verification_url"] = url + "?token=" + token
|
||||
message = addEmailTemplate(message, data, "verify_email.tmpl")
|
||||
// bodyMessage := sender.WriteHTMLEmail(Receiver, Subject, message)
|
||||
|
||||
err := SendMail(Receiver, Subject, message)
|
||||
if err != nil {
|
||||
log.Println("=> error sending email:", err)
|
||||
}
|
||||
return err
|
||||
}
|
|
@ -114,6 +114,7 @@ type ComplexityRoot struct {
|
|||
AdminSignup func(childComplexity int, params model.AdminSignupInput) int
|
||||
DeleteUser func(childComplexity int, params model.DeleteUserInput) int
|
||||
ForgotPassword func(childComplexity int, params model.ForgotPasswordInput) 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
|
||||
|
@ -208,6 +209,7 @@ type MutationResolver interface {
|
|||
AdminLogin(ctx context.Context, params model.AdminLoginInput) (*model.Response, error)
|
||||
AdminLogout(ctx context.Context) (*model.Response, error)
|
||||
UpdateEnv(ctx context.Context, params model.UpdateEnvInput) (*model.Response, error)
|
||||
InviteMembers(ctx context.Context, params model.InviteMemberInput) (*model.Response, error)
|
||||
}
|
||||
type QueryResolver interface {
|
||||
Meta(ctx context.Context) (*model.Meta, error)
|
||||
|
@ -660,6 +662,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||
|
||||
return e.complexity.Mutation.ForgotPassword(childComplexity, args["params"].(model.ForgotPasswordInput)), true
|
||||
|
||||
case "Mutation._invite_members":
|
||||
if e.complexity.Mutation.InviteMembers == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_Mutation__invite_members_args(context.TODO(), rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Mutation.InviteMembers(childComplexity, args["params"].(model.InviteMemberInput)), true
|
||||
|
||||
case "Mutation.login":
|
||||
if e.complexity.Mutation.Login == nil {
|
||||
break
|
||||
|
@ -1434,6 +1448,11 @@ input OAuthRevokeInput {
|
|||
refresh_token: String!
|
||||
}
|
||||
|
||||
input InviteMemberInput {
|
||||
emails: [String!]!
|
||||
redirect_uri: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
signup(params: SignUpInput!): AuthResponse!
|
||||
login(params: LoginInput!): AuthResponse!
|
||||
|
@ -1452,6 +1471,7 @@ type Mutation {
|
|||
_admin_login(params: AdminLoginInput!): Response!
|
||||
_admin_logout: Response!
|
||||
_update_env(params: UpdateEnvInput!): Response!
|
||||
_invite_members(params: InviteMemberInput!): Response!
|
||||
}
|
||||
|
||||
type Query {
|
||||
|
@ -1517,6 +1537,21 @@ func (ec *executionContext) field_Mutation__delete_user_args(ctx context.Context
|
|||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Mutation__invite_members_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 model.InviteMemberInput
|
||||
if tmp, ok := rawArgs["params"]; ok {
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
|
||||
arg0, err = ec.unmarshalNInviteMemberInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐInviteMemberInput(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{}{}
|
||||
|
@ -4182,6 +4217,48 @@ func (ec *executionContext) _Mutation__update_env(ctx context.Context, field gra
|
|||
return ec.marshalNResponse2ᚖgithubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Mutation__invite_members(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__invite_members_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().InviteMembers(rctx, args["params"].(model.InviteMemberInput))
|
||||
})
|
||||
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 {
|
||||
|
@ -6914,6 +6991,37 @@ func (ec *executionContext) unmarshalInputForgotPasswordInput(ctx context.Contex
|
|||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputInviteMemberInput(ctx context.Context, obj interface{}) (model.InviteMemberInput, error) {
|
||||
var it model.InviteMemberInput
|
||||
asMap := map[string]interface{}{}
|
||||
for k, v := range obj.(map[string]interface{}) {
|
||||
asMap[k] = v
|
||||
}
|
||||
|
||||
for k, v := range asMap {
|
||||
switch k {
|
||||
case "emails":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("emails"))
|
||||
it.Emails, err = ec.unmarshalNString2ᚕstringᚄ(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "redirect_uri":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("redirect_uri"))
|
||||
it.RedirectURI, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputLoginInput(ctx context.Context, obj interface{}) (model.LoginInput, error) {
|
||||
var it model.LoginInput
|
||||
asMap := map[string]interface{}{}
|
||||
|
@ -8182,6 +8290,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
|
|||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "_invite_members":
|
||||
out.Values[i] = ec._Mutation__invite_members(ctx, field)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
|
@ -8911,6 +9024,11 @@ func (ec *executionContext) marshalNInt642int64(ctx context.Context, sel ast.Sel
|
|||
return res
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNInviteMemberInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐInviteMemberInput(ctx context.Context, v interface{}) (model.InviteMemberInput, error) {
|
||||
res, err := ec.unmarshalInputInviteMemberInput(ctx, v)
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNLoginInput2githubᚗcomᚋauthorizerdevᚋauthorizerᚋserverᚋgraphᚋmodelᚐLoginInput(ctx context.Context, v interface{}) (model.LoginInput, error) {
|
||||
res, err := ec.unmarshalInputLoginInput(ctx, v)
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
|
|
|
@ -74,6 +74,11 @@ type ForgotPasswordInput struct {
|
|||
RedirectURI *string `json:"redirect_uri"`
|
||||
}
|
||||
|
||||
type InviteMemberInput struct {
|
||||
Emails []string `json:"emails"`
|
||||
RedirectURI *string `json:"redirect_uri"`
|
||||
}
|
||||
|
||||
type LoginInput struct {
|
||||
Email string `json:"email"`
|
||||
Password string `json:"password"`
|
||||
|
|
|
@ -272,6 +272,11 @@ input OAuthRevokeInput {
|
|||
refresh_token: String!
|
||||
}
|
||||
|
||||
input InviteMemberInput {
|
||||
emails: [String!]!
|
||||
redirect_uri: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
signup(params: SignUpInput!): AuthResponse!
|
||||
login(params: LoginInput!): AuthResponse!
|
||||
|
@ -290,6 +295,7 @@ type Mutation {
|
|||
_admin_login(params: AdminLoginInput!): Response!
|
||||
_admin_logout: Response!
|
||||
_update_env(params: UpdateEnvInput!): Response!
|
||||
_invite_members(params: InviteMemberInput!): Response!
|
||||
}
|
||||
|
||||
type Query {
|
||||
|
|
|
@ -75,6 +75,10 @@ func (r *mutationResolver) UpdateEnv(ctx context.Context, params model.UpdateEnv
|
|||
return resolvers.UpdateEnvResolver(ctx, params)
|
||||
}
|
||||
|
||||
func (r *mutationResolver) InviteMembers(ctx context.Context, params model.InviteMemberInput) (*model.Response, error) {
|
||||
return resolvers.InviteMembersResolver(ctx, params)
|
||||
}
|
||||
|
||||
func (r *queryResolver) Meta(ctx context.Context) (*model.Meta, error) {
|
||||
return resolvers.MetaResolver(ctx)
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ func ForgotPasswordResolver(ctx context.Context, params model.ForgotPasswordInpu
|
|||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
redirectURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAppURL)
|
||||
redirectURL := utils.GetAppURL(gc) + "/reset-password"
|
||||
if params.RedirectURI != nil {
|
||||
redirectURL = *params.RedirectURI
|
||||
}
|
||||
|
|
134
server/resolvers/invite_members.go
Normal file
134
server/resolvers/invite_members.go
Normal file
|
@ -0,0 +1,134 @@
|
|||
package resolvers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
"github.com/authorizerdev/authorizer/server/db"
|
||||
"github.com/authorizerdev/authorizer/server/db/models"
|
||||
emailservice "github.com/authorizerdev/authorizer/server/email"
|
||||
"github.com/authorizerdev/authorizer/server/envstore"
|
||||
"github.com/authorizerdev/authorizer/server/graph/model"
|
||||
"github.com/authorizerdev/authorizer/server/token"
|
||||
"github.com/authorizerdev/authorizer/server/utils"
|
||||
)
|
||||
|
||||
// InviteMembersResolver resolver to invite members
|
||||
func InviteMembersResolver(ctx context.Context, params model.InviteMemberInput) (*model.Response, error) {
|
||||
gc, err := utils.GinContextFromContext(ctx)
|
||||
var res *model.Response
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
if !token.IsSuperAdmin(gc) {
|
||||
return res, errors.New("unauthorized")
|
||||
}
|
||||
|
||||
// this feature is only allowed if email server is configured
|
||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) {
|
||||
return res, errors.New("email sending is disabled")
|
||||
}
|
||||
|
||||
if envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableBasicAuthentication) && envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) {
|
||||
return res, errors.New("either basic authentication or magic link login is required")
|
||||
}
|
||||
|
||||
// filter valid emails
|
||||
emails := []string{}
|
||||
for _, email := range params.Emails {
|
||||
if utils.IsValidEmail(email) {
|
||||
emails = append(emails, email)
|
||||
}
|
||||
}
|
||||
|
||||
if len(emails) == 0 {
|
||||
res.Message = "No valid emails found"
|
||||
return res, errors.New("no valid emails found")
|
||||
}
|
||||
|
||||
// TODO: optimise to use like query instead of looping through emails and getting user individually
|
||||
// for each emails check if emails exists in db
|
||||
newEmails := []string{}
|
||||
for _, email := range emails {
|
||||
_, err := db.Provider.GetUserByEmail(email)
|
||||
if err != nil {
|
||||
log.Printf("%s user not found. inviting user.", email)
|
||||
newEmails = append(newEmails, email)
|
||||
} else {
|
||||
log.Println("%s user already exists. skipping.", email)
|
||||
}
|
||||
}
|
||||
|
||||
if len(newEmails) == 0 {
|
||||
res.Message = "All emails already exist"
|
||||
return res, errors.New("all emails already exist")
|
||||
}
|
||||
|
||||
// invite new emails
|
||||
for _, email := range newEmails {
|
||||
|
||||
user := models.User{
|
||||
Email: email,
|
||||
Roles: strings.Join(envstore.EnvStoreObj.GetSliceStoreEnvVariable(constants.EnvKeyDefaultRoles), ","),
|
||||
}
|
||||
redirectURL := utils.GetAppURL(gc) + "/verify_email"
|
||||
if params.RedirectURI != nil {
|
||||
redirectURL = *params.RedirectURI
|
||||
}
|
||||
|
||||
_, nonceHash, err := utils.GenerateNonce()
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
verificationToken, err := token.CreateVerificationToken(email, constants.VerificationTypeForgotPassword, redirectURL, nonceHash, redirectURL)
|
||||
if err != nil {
|
||||
log.Println(`error generating token`, err)
|
||||
}
|
||||
|
||||
verificationRequest := models.VerificationRequest{
|
||||
Token: verificationToken,
|
||||
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
||||
Email: email,
|
||||
Nonce: nonceHash,
|
||||
RedirectURI: redirectURL,
|
||||
}
|
||||
|
||||
// use magic link login if that option is on
|
||||
if !envstore.EnvStoreObj.GetBoolStoreEnvVariable(constants.EnvKeyDisableMagicLinkLogin) {
|
||||
user.SignupMethods = constants.SignupMethodMagicLinkLogin
|
||||
verificationRequest.Identifier = constants.VerificationTypeMagicLinkLogin
|
||||
} else {
|
||||
// use basic authentication if that option is on
|
||||
user.SignupMethods = constants.SignupMethodBasicAuth
|
||||
verificationRequest.Identifier = constants.VerificationTypeForgotPassword
|
||||
|
||||
redirectURL = utils.GetAppURL(gc) + "/setup-password"
|
||||
if params.RedirectURI != nil {
|
||||
redirectURL = *params.RedirectURI
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
user, err = db.Provider.AddUser(user)
|
||||
if err != nil {
|
||||
log.Printf("error inviting user: %s, err: %v", email, err)
|
||||
return res, err
|
||||
}
|
||||
|
||||
_, err = db.Provider.AddVerificationRequest(verificationRequest)
|
||||
if err != nil {
|
||||
log.Printf("error inviting user: %s, err: %v", email, err)
|
||||
return res, err
|
||||
}
|
||||
|
||||
go emailservice.InviteEmail(email, verificationToken, redirectURL)
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
|
@ -123,7 +123,7 @@ func MagicLinkLoginResolver(ctx context.Context, params model.MagicLinkLoginInpu
|
|||
if params.Scope != nil && len(params.Scope) > 0 {
|
||||
redirectURLParams = redirectURLParams + "&scope=" + strings.Join(params.Scope, " ")
|
||||
}
|
||||
redirectURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAppURL)
|
||||
redirectURL := utils.GetAppURL(gc)
|
||||
if params.RedirectURI != nil {
|
||||
redirectURL = *params.RedirectURI
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ func SignupResolver(ctx context.Context, params model.SignUpInput) (*model.AuthR
|
|||
return res, err
|
||||
}
|
||||
verificationType := constants.VerificationTypeBasicAuthSignup
|
||||
redirectURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAppURL)
|
||||
redirectURL := utils.GetAppURL(gc)
|
||||
verificationToken, err := token.CreateVerificationToken(params.Email, verificationType, hostname, nonceHash, redirectURL)
|
||||
if err != nil {
|
||||
return res, err
|
||||
|
|
|
@ -134,7 +134,7 @@ func UpdateProfileResolver(ctx context.Context, params model.UpdateProfileInput)
|
|||
return res, err
|
||||
}
|
||||
verificationType := constants.VerificationTypeUpdateEmail
|
||||
redirectURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAppURL)
|
||||
redirectURL := utils.GetAppURL(gc)
|
||||
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
|
||||
if err != nil {
|
||||
log.Println(`error generating token`, err)
|
||||
|
|
|
@ -106,7 +106,7 @@ func UpdateUserResolver(ctx context.Context, params model.UpdateUserInput) (*mod
|
|||
return res, err
|
||||
}
|
||||
verificationType := constants.VerificationTypeUpdateEmail
|
||||
redirectURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAppURL)
|
||||
redirectURL := utils.GetAppURL(gc)
|
||||
verificationToken, err := token.CreateVerificationToken(newEmail, verificationType, hostname, nonceHash, redirectURL)
|
||||
if err != nil {
|
||||
log.Println(`error generating token`, err)
|
||||
|
|
|
@ -4,6 +4,8 @@ import (
|
|||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/authorizerdev/authorizer/server/constants"
|
||||
"github.com/authorizerdev/authorizer/server/envstore"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
|
@ -71,3 +73,12 @@ func GetDomainName(uri string) string {
|
|||
|
||||
return host
|
||||
}
|
||||
|
||||
// GetAppURL to get /app/ url if not configured by user
|
||||
func GetAppURL(gc *gin.Context) string {
|
||||
envAppURL := envstore.EnvStoreObj.GetStringStoreEnvVariable(constants.EnvKeyAppURL)
|
||||
if envAppURL == "" {
|
||||
envAppURL = GetHost(gc) + "/app/"
|
||||
}
|
||||
return envAppURL
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user