github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/service/invite_friends.go (about) 1 package service 2 3 import ( 4 "fmt" 5 "strings" 6 7 email_utils "github.com/keybase/client/go/emails" 8 "github.com/keybase/client/go/invitefriends" 9 "github.com/keybase/client/go/libkb" 10 keybase1 "github.com/keybase/client/go/protocol/keybase1" 11 "github.com/keybase/go-framed-msgpack-rpc/rpc" 12 13 "golang.org/x/net/context" 14 ) 15 16 type InviteFriendsHandler struct { 17 libkb.Contextified 18 *BaseHandler 19 } 20 21 func NewInviteFriendsHandler(xp rpc.Transporter, g *libkb.GlobalContext) *InviteFriendsHandler { 22 handler := &InviteFriendsHandler{ 23 Contextified: libkb.NewContextified(g), 24 BaseHandler: NewBaseHandler(g, xp), 25 } 26 return handler 27 } 28 29 var _ keybase1.InviteFriendsInterface = (*InviteFriendsHandler)(nil) 30 31 func (h *InviteFriendsHandler) InvitePeople(ctx context.Context, arg keybase1.InvitePeopleArg) (succeeded int, err error) { 32 mctx := libkb.NewMetaContext(ctx, h.G()) 33 defer mctx.Trace("InviteFriendsHandler#InvitePeople", &err)() 34 35 if err := assertLoggedIn(ctx, h.G()); err != nil { 36 mctx.Debug("not logged in err: %v", err) 37 return 0, err 38 } 39 40 allOK := true 41 var assertions []string 42 if arg.Emails.EmailsFromContacts != nil { 43 for _, email := range *arg.Emails.EmailsFromContacts { 44 assertion, parseErr := libkb.ParseAssertionURLKeyValue(mctx.G().MakeAssertionContext(mctx), "email", email.String(), false) 45 if parseErr != nil { 46 allOK = false 47 mctx.Debug("failed to parse email %q; skipping: %s", email, parseErr) 48 continue 49 } 50 assertions = append(assertions, assertion.String()) 51 } 52 } 53 if arg.Emails.CommaSeparatedEmailsFromUser != nil { 54 var malformed []string 55 parsedEmails := email_utils.ParseSeparatedEmails(mctx, *arg.Emails.CommaSeparatedEmailsFromUser, &malformed) 56 if len(malformed) > 0 { 57 allOK = false 58 } 59 60 actx := mctx.G().MakeAssertionContext(mctx) 61 for _, email := range parsedEmails { 62 // `strict` argument here doesn't actually do anything for "email" assertions. 63 assertion, parseErr := libkb.ParseAssertionURLKeyValue(actx, "email", email, false /* strict */) 64 if parseErr != nil { 65 mctx.Debug("failed to create assertion from email %q: %s", email, parseErr) 66 allOK = false 67 continue 68 } 69 assertions = append(assertions, assertion.String()) 70 } 71 } 72 for _, phone := range arg.Phones { 73 phoneStr := strings.TrimPrefix(phone.String(), "+") 74 assertion, parseErr := libkb.ParseAssertionURLKeyValue(mctx.G().MakeAssertionContext(mctx), "phone", phoneStr, false) 75 if parseErr != nil { 76 allOK = false 77 mctx.Debug("failed to parse phone number %q; skipping: %s", phone, parseErr) 78 continue 79 } 80 assertions = append(assertions, assertion.String()) 81 } 82 83 if len(assertions) == 0 { 84 if allOK { 85 return 0, nil 86 } 87 return 0, fmt.Errorf("failed to parse any email or phone number") 88 } 89 90 type apiRes struct { 91 libkb.AppStatusEmbed 92 } 93 payload := make(libkb.JSONPayload) 94 payload["assertions"] = assertions 95 apiArg := libkb.APIArg{ 96 Endpoint: "invite_friends/invite", 97 SessionType: libkb.APISessionTypeREQUIRED, 98 JSONPayload: payload, 99 } 100 var res apiRes 101 err = mctx.G().API.PostDecode(mctx, apiArg, &res) 102 if err != nil { 103 return 0, err 104 } 105 return len(assertions), nil 106 } 107 108 func (h *InviteFriendsHandler) GetInviteCounts(ctx context.Context) (counts keybase1.InviteCounts, err error) { 109 mctx := libkb.NewMetaContext(ctx, h.G()) 110 defer mctx.Trace("InviteFriendsHandler#GetInviteCounts", &err)() 111 112 return invitefriends.GetCounts(mctx) 113 } 114 115 func (h *InviteFriendsHandler) RequestInviteCounts(ctx context.Context) (err error) { 116 mctx := libkb.NewMetaContext(ctx, h.G()) 117 defer mctx.Trace("InviteFriendsHandler#RequestInviteCounts", &err)() 118 119 return invitefriends.RequestNotification(mctx) 120 }