github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/email_change.go (about) 1 // Copyright 2015 Keybase, Inc. All rights reserved. Use of 2 // this source code is governed by the included BSD license. 3 4 package engine 5 6 import ( 7 "github.com/keybase/client/go/libkb" 8 keybase1 "github.com/keybase/client/go/protocol/keybase1" 9 jsonw "github.com/keybase/go-jsonw" 10 ) 11 12 // EmailChange is an engine that changes a user's email via signed statement. 13 type EmailChange struct { 14 arg *keybase1.EmailChangeArg 15 libkb.Contextified 16 } 17 18 // NewEmailChange creates a new engine for changing a user's email 19 // address via signature (and therefore without passphrase required) 20 func NewEmailChange(g *libkb.GlobalContext, a *keybase1.EmailChangeArg) *EmailChange { 21 return &EmailChange{ 22 arg: a, 23 Contextified: libkb.NewContextified(g), 24 } 25 } 26 27 // Name provides the name of the engine for the engine interface 28 func (c *EmailChange) Name() string { 29 return "EmailChange" 30 } 31 32 // Prereqs returns engine prereqs 33 func (c *EmailChange) Prereqs() Prereqs { 34 return Prereqs{Device: true} 35 } 36 37 // RequiredUIs returns the required UIs. 38 func (c *EmailChange) RequiredUIs() []libkb.UIKind { 39 return []libkb.UIKind{ 40 libkb.SecretUIKind, 41 } 42 } 43 44 // SubConsumers requires the other UI consumers of this engine 45 func (c *EmailChange) SubConsumers() []libkb.UIConsumer { 46 return []libkb.UIConsumer{} 47 } 48 49 // Run the engine 50 func (c *EmailChange) Run(m libkb.MetaContext) (err error) { 51 defer m.Trace("EmailChange#Run", &err)() 52 53 if !libkb.CheckEmail.F(c.arg.NewEmail) { 54 return libkb.BadEmailError{} 55 } 56 57 var me *libkb.User 58 me, err = libkb.LoadMe(libkb.NewLoadUserArgWithMetaContext(m).WithForceReload()) 59 if err != nil { 60 return err 61 } 62 63 // need unlocked signing key 64 ska := libkb.SecretKeyArg{ 65 Me: me, 66 KeyType: libkb.DeviceSigningKeyType, 67 } 68 arg := m.SecretKeyPromptArg(ska, "tracking signature") 69 signingKey, err := m.G().Keyrings.GetSecretKeyWithPrompt(m, arg) 70 if err != nil { 71 return err 72 } 73 if signingKey == nil { 74 return libkb.NoSecretKeyError{} 75 } 76 var proof *jsonw.Wrapper 77 proof, err = me.UpdateEmailProof(m, signingKey, c.arg.NewEmail) 78 if err != nil { 79 return err 80 } 81 var sig string 82 sig, _, _, err = libkb.SignJSON(proof, signingKey) 83 if err != nil { 84 return err 85 } 86 87 _, err = m.G().API.Post(m, libkb.APIArg{ 88 Endpoint: "account/email_update_signed", 89 SessionType: libkb.APISessionTypeREQUIRED, 90 Args: libkb.HTTPArgs{ 91 "sig": libkb.S{Val: sig}, 92 "signing_kid": libkb.S{Val: signingKey.GetKID().String()}, 93 }, 94 }) 95 96 if err != nil { 97 return err 98 } 99 100 return nil 101 }