github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/engine/signup_join.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 "encoding/hex" 8 "fmt" 9 10 "github.com/keybase/client/go/libkb" 11 keybase1 "github.com/keybase/client/go/protocol/keybase1" 12 ) 13 14 type SignupJoinEngine struct { 15 uv keybase1.UserVersion 16 session string 17 csrf string 18 username libkb.NormalizedUsername 19 ppGen libkb.PassphraseGeneration 20 libkb.Contextified 21 } 22 23 func NewSignupJoinEngine(g *libkb.GlobalContext) *SignupJoinEngine { 24 return &SignupJoinEngine{Contextified: libkb.NewContextified(g)} 25 } 26 27 func (s *SignupJoinEngine) Init() error { 28 return nil 29 } 30 31 func (s *SignupJoinEngine) CheckRegistered() (err error) { 32 s.G().Log.Debug("+ libkb.SignupJoinEngine::CheckRegistered") 33 if cr := s.G().Env.GetConfig(); cr == nil { 34 err = fmt.Errorf("No configuration file available") 35 } else if u := cr.GetUID(); u.Exists() { 36 err = libkb.AlreadyRegisteredError{UID: u} 37 } 38 s.G().Log.Debug("- libkb.SignupJoinEngine::CheckRegistered -> %s", libkb.ErrToOk(err)) 39 return err 40 } 41 42 type SignupJoinEngineRunArg struct { 43 Username string 44 Email string 45 InviteCode string 46 PWHash []byte 47 PWSalt []byte 48 RandomPW bool 49 PDPKA5KID keybase1.KID 50 SkipMail bool 51 VerifyEmail bool 52 BotToken keybase1.BotToken 53 } 54 55 func (s *SignupJoinEngine) Post(m libkb.MetaContext, arg SignupJoinEngineRunArg) (err error) { 56 var res *libkb.APIRes 57 var ppGenTmp int 58 postArgs := libkb.HTTPArgs{ 59 "salt": libkb.S{Val: hex.EncodeToString(arg.PWSalt)}, 60 "pwh": libkb.S{Val: hex.EncodeToString(arg.PWHash)}, 61 "random_pw": libkb.B{Val: arg.RandomPW}, 62 "username": libkb.S{Val: arg.Username}, 63 "invitation_id": libkb.S{Val: arg.InviteCode}, 64 "pwh_version": libkb.I{Val: int(libkb.ClientTriplesecVersion)}, 65 "skip_mail": libkb.B{Val: arg.SkipMail}, 66 "pdpka5_kid": libkb.S{Val: arg.PDPKA5KID.String()}, 67 "platform": libkb.S{Val: libkb.GetPlatformString()}, 68 "verify_email": libkb.B{Val: arg.VerifyEmail}, 69 } 70 if len(arg.Email) > 0 { 71 postArgs["email"] = libkb.S{Val: arg.Email} 72 } else { 73 postArgs["no_email"] = libkb.B{Val: true} 74 } 75 if arg.BotToken.Exists() { 76 postArgs["bot_token"] = libkb.S{Val: arg.BotToken.String()} 77 } 78 res, err = m.G().API.Post(m, libkb.APIArg{ 79 Endpoint: "signup", 80 Args: postArgs, 81 }) 82 if err == nil { 83 s.username = libkb.NewNormalizedUsername(arg.Username) 84 libkb.GetUIDVoid(res.Body.AtKey("uid"), &s.uv.Uid, &err) 85 res.Body.AtKey("session").GetStringVoid(&s.session, &err) 86 res.Body.AtKey("csrf_token").GetStringVoid(&s.csrf, &err) 87 res.Body.AtPath("me.basics.passphrase_generation").GetIntVoid(&ppGenTmp, &err) 88 } 89 if err == nil { 90 err = libkb.CheckUIDAgainstUsername(s.uv.Uid, arg.Username) 91 s.ppGen = libkb.PassphraseGeneration(ppGenTmp) 92 } 93 return err 94 } 95 96 type SignupJoinEngineRunRes struct { 97 PassphraseOk bool 98 PostOk bool 99 WriteOk bool 100 UV keybase1.UserVersion 101 User *libkb.User 102 Err error 103 PpGen libkb.PassphraseGeneration 104 } 105 106 func (r SignupJoinEngineRunRes) Error() string { 107 return r.Err.Error() 108 } 109 110 func (s *SignupJoinEngine) Run(m libkb.MetaContext, arg SignupJoinEngineRunArg) (res SignupJoinEngineRunRes) { 111 res.PassphraseOk = true 112 113 if res.Err = s.Post(m, arg); res.Err != nil { 114 return 115 } 116 res.PostOk = true 117 if res.Err = s.WriteOut(m, arg); res.Err != nil { 118 return 119 } 120 res.WriteOk = true 121 res.UV = s.uv 122 res.PpGen = s.ppGen 123 return 124 } 125 126 func (s *SignupJoinEngine) WriteOut(m libkb.MetaContext, arg SignupJoinEngineRunArg) error { 127 lctx := m.LoginContext() 128 if err := lctx.CreateLoginSessionWithSalt(s.username.String(), arg.PWSalt); err != nil { 129 return err 130 } 131 var nilDeviceID keybase1.DeviceID 132 if err := lctx.SaveState(s.session, s.csrf, s.username, s.uv, nilDeviceID); err != nil { 133 return err 134 } 135 if arg.BotToken.Exists() { 136 m.Debug("SignupJoinEngine#WriteOut: not saving config since in bot mode") 137 return nil 138 } 139 // Switching to a new user is an operation on the GlobalContext, and will atomically 140 // update the config file and alter the current ActiveDevice. So farm out to over there. 141 return m.SwitchUserNewConfig(s.uv.Uid, s.username, arg.PWSalt, nilDeviceID) 142 } 143 144 func (s *SignupJoinEngine) PostInviteRequest(m libkb.MetaContext, arg libkb.InviteRequestArg) error { 145 return libkb.PostInviteRequest(m, arg) 146 }