github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/phonenumbers/user.go (about)

     1  // Copyright 2018 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package phonenumbers
     5  
     6  import (
     7  	"github.com/keybase/client/go/contacts"
     8  	"github.com/keybase/client/go/libkb"
     9  	"github.com/keybase/client/go/protocol/keybase1"
    10  )
    11  
    12  // AddPhoneNumber calls API to add phone number to currently logged in account.
    13  func AddPhoneNumber(mctx libkb.MetaContext, phoneNumber keybase1.PhoneNumber, visibility keybase1.IdentityVisibility) error {
    14  	// First try to delete if we have a superseded item for this phone number already
    15  	nums, err := GetPhoneNumbers(mctx)
    16  	if err == nil {
    17  		for _, num := range nums {
    18  			if num.Superseded && num.PhoneNumber == phoneNumber {
    19  				err = DeletePhoneNumber(mctx, num.PhoneNumber)
    20  				if err != nil {
    21  					mctx.Warning("error deleting superseded number on add: %s", err)
    22  				}
    23  			}
    24  		}
    25  	} else {
    26  		mctx.Warning("error fetching numbers on add: %s", err)
    27  	}
    28  
    29  	payload := make(libkb.JSONPayload)
    30  	payload["phone_number"] = phoneNumber
    31  	payload["visibility"] = visibility
    32  
    33  	arg := libkb.APIArg{
    34  		Endpoint:    "user/phone_numbers",
    35  		JSONPayload: payload,
    36  		SessionType: libkb.APISessionTypeREQUIRED,
    37  	}
    38  
    39  	_, err = mctx.G().API.PostJSON(mctx, arg)
    40  	return err
    41  }
    42  
    43  // VerifyPhoneNumber calls API to verify previously added phone number using
    44  // verification code.
    45  func VerifyPhoneNumber(mctx libkb.MetaContext, phoneNumber keybase1.PhoneNumber, code string) error {
    46  	payload := make(libkb.JSONPayload)
    47  	payload["phone_number"] = phoneNumber
    48  	payload["verification_code"] = code
    49  
    50  	arg := libkb.APIArg{
    51  		Endpoint:    "user/phone_number_verify",
    52  		JSONPayload: payload,
    53  		SessionType: libkb.APISessionTypeREQUIRED,
    54  	}
    55  
    56  	_, err := mctx.G().API.PostJSON(mctx, arg)
    57  	return err
    58  }
    59  
    60  type phoneNumbersResponse struct {
    61  	libkb.AppStatusEmbed
    62  	PhoneNumbers []keybase1.UserPhoneNumber `json:"phone_numbers"`
    63  }
    64  
    65  // GetPhoneNumbers calls API to fetch list of phone numbers attached to
    66  // currently logged user.
    67  func GetPhoneNumbers(mctx libkb.MetaContext) ([]keybase1.UserPhoneNumber, error) {
    68  	arg := libkb.APIArg{
    69  		Endpoint:    "user/phone_numbers",
    70  		SessionType: libkb.APISessionTypeREQUIRED,
    71  	}
    72  	var resp phoneNumbersResponse
    73  	err := mctx.G().API.GetDecode(mctx, arg, &resp)
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	return resp.PhoneNumbers, nil
    78  }
    79  
    80  func clearPhoneNumbersFromContactCache(mctx libkb.MetaContext, phoneNumber keybase1.PhoneNumber) {
    81  	// Now remove this number from contact lookup cache and from synced
    82  	// contacts.
    83  	cache := contacts.NewContactCacheStore(mctx.G())
    84  	cache.RemoveContactsCacheEntries(mctx, &phoneNumber, nil /* email */)
    85  	if sync := mctx.G().SyncedContactList; sync != nil {
    86  		sync.UnresolveContactsWithComponent(mctx, &phoneNumber, nil /* email */)
    87  	}
    88  }
    89  
    90  func DeletePhoneNumber(mctx libkb.MetaContext, phoneNumber keybase1.PhoneNumber) error {
    91  	payload := make(libkb.JSONPayload)
    92  	payload["phone_number"] = phoneNumber
    93  
    94  	arg := libkb.APIArg{
    95  		Endpoint:    "user/phone_numbers",
    96  		JSONPayload: payload,
    97  		SessionType: libkb.APISessionTypeREQUIRED,
    98  	}
    99  
   100  	_, err := mctx.G().API.Delete(mctx, arg)
   101  	if err != nil {
   102  		return err
   103  	}
   104  	clearPhoneNumbersFromContactCache(mctx, phoneNumber)
   105  	return nil
   106  }
   107  
   108  func SetVisibilityPhoneNumber(mctx libkb.MetaContext, phoneNumber keybase1.PhoneNumber, visibility keybase1.IdentityVisibility) error {
   109  	payload := make(libkb.JSONPayload)
   110  	payload["phone_number"] = phoneNumber
   111  	payload["visibility"] = visibility
   112  
   113  	arg := libkb.APIArg{
   114  		Endpoint:    "user/phone_number_visibility",
   115  		JSONPayload: payload,
   116  		SessionType: libkb.APISessionTypeREQUIRED,
   117  	}
   118  
   119  	_, err := mctx.G().API.PostJSON(mctx, arg)
   120  	if err != nil {
   121  		return nil
   122  	}
   123  	if visibility == keybase1.IdentityVisibility_PRIVATE {
   124  		clearPhoneNumbersFromContactCache(mctx, phoneNumber)
   125  	}
   126  	return nil
   127  }
   128  
   129  func SetVisibilityAllPhoneNumber(mctx libkb.MetaContext, visibility keybase1.IdentityVisibility) error {
   130  	payload := make(libkb.JSONPayload)
   131  	payload["visibility"] = visibility
   132  	payload["all"] = true
   133  
   134  	arg := libkb.APIArg{
   135  		Endpoint:    "user/phone_number_visibility",
   136  		JSONPayload: payload,
   137  		SessionType: libkb.APISessionTypeREQUIRED,
   138  	}
   139  
   140  	_, err := mctx.G().API.PostJSON(mctx, arg)
   141  	return err
   142  }