• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / gotrue / 8135412125

04 Mar 2024 03:34AM UTC coverage: 65.142% (+0.1%) from 65.009%
8135412125

push

github

web-flow
fix: refactor request params to use generics (#1464)

## What kind of change does this PR introduce?
* Introduce a new method `retrieveRequestParams` which makes use of
generics to parse a request
* This will help to simplify parsing a request from:
```go

params := RequestParams{}
body, err := getBodyBytes(r)
if err != nil {
  return nil, badRequestError("Could not read body").WithInternalError(err)
}

if err := json.Unmarshal(body, &params); err != nil {
  return nil, badRequestError("Could not decode request params: %v", err)
}
```
to 
```go
params := &Request{}
err := retrieveRequestParams(req, params)
```

## TODO
- [x] Add type constraint instead of using `any`

48 of 69 new or added lines in 19 files covered. (69.57%)

19 existing lines in 14 files now uncovered.

7806 of 11983 relevant lines covered (65.14%)

59.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.12
/internal/api/invite.go
1
package api
2

3
import (
4
        "net/http"
5

6
        "github.com/fatih/structs"
7
        "github.com/supabase/auth/internal/api/provider"
8
        "github.com/supabase/auth/internal/models"
9
        "github.com/supabase/auth/internal/storage"
10
        "github.com/supabase/auth/internal/utilities"
11
)
12

13
// InviteParams are the parameters the Signup endpoint accepts
14
type InviteParams struct {
15
        Email string                 `json:"email"`
16
        Data  map[string]interface{} `json:"data"`
17
}
18

19
// Invite is the endpoint for inviting a new user
20
func (a *API) Invite(w http.ResponseWriter, r *http.Request) error {
4✔
21
        ctx := r.Context()
4✔
22
        db := a.db.WithContext(ctx)
4✔
23
        config := a.config
4✔
24
        adminUser := getAdminUser(ctx)
4✔
25
        params := &InviteParams{}
4✔
26
        if err := retrieveRequestParams(r, params); err != nil {
4✔
NEW
27
                return err
×
UNCOV
28
        }
×
29

30
        var err error
4✔
31
        params.Email, err = validateEmail(params.Email)
4✔
32
        if err != nil {
4✔
33
                return err
×
34
        }
×
35

36
        aud := a.requestAud(ctx, r)
4✔
37
        user, err := models.FindUserByEmailAndAudience(db, params.Email, aud)
4✔
38
        if err != nil && !models.IsNotFoundError(err) {
4✔
39
                return internalServerError("Database error finding user").WithInternalError(err)
×
40
        }
×
41

42
        err = db.Transaction(func(tx *storage.Connection) error {
8✔
43
                if user != nil {
4✔
44
                        if user.IsConfirmed() {
×
45
                                return unprocessableEntityError(DuplicateEmailMsg)
×
46
                        }
×
47
                } else {
4✔
48
                        signupParams := SignupParams{
4✔
49
                                Email:    params.Email,
4✔
50
                                Data:     params.Data,
4✔
51
                                Aud:      aud,
4✔
52
                                Provider: "email",
4✔
53
                        }
4✔
54

4✔
55
                        // because params above sets no password, this method
4✔
56
                        // is not computationally hard so it can be used within
4✔
57
                        // a database transaction
4✔
58
                        user, err = signupParams.ToUserModel(false /* <- isSSOUser */)
4✔
59
                        if err != nil {
4✔
60
                                return err
×
61
                        }
×
62

63
                        user, err = a.signupNewUser(tx, user)
4✔
64
                        if err != nil {
4✔
65
                                return err
×
66
                        }
×
67
                        identity, err := a.createNewIdentity(tx, user, "email", structs.Map(provider.Claims{
4✔
68
                                Subject: user.ID.String(),
4✔
69
                                Email:   user.GetEmail(),
4✔
70
                        }))
4✔
71
                        if err != nil {
4✔
72
                                return err
×
73
                        }
×
74
                        user.Identities = []models.Identity{*identity}
4✔
75
                }
76

77
                if terr := models.NewAuditLogEntry(r, tx, adminUser, models.UserInvitedAction, "", map[string]interface{}{
4✔
78
                        "user_id":    user.ID,
4✔
79
                        "user_email": user.Email,
4✔
80
                }); terr != nil {
4✔
81
                        return terr
×
82
                }
×
83

84
                mailer := a.Mailer(ctx)
4✔
85
                referrer := utilities.GetReferrer(r, config)
4✔
86
                externalURL := getExternalHost(ctx)
4✔
87
                if err := sendInvite(tx, user, mailer, referrer, externalURL, config.Mailer.OtpLength); err != nil {
4✔
88
                        return internalServerError("Error inviting user").WithInternalError(err)
×
89
                }
×
90
                return nil
4✔
91
        })
92
        if err != nil {
4✔
93
                return err
×
94
        }
×
95

96
        return sendJSON(w, http.StatusOK, user)
4✔
97
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc