Merge remote-tracking branch 'upstream/main' into merge-gramsrv-9106877
This commit is contained in:
commit
ac6a50c5ff
697 changed files with 100880 additions and 8052 deletions
|
|
@ -870,27 +870,24 @@ func (s *Service) CancelCodeForAuthKey(ctx context.Context, authKeyID [8]byte, p
|
|||
// never offers a "Can't access this email?" escape hatch that can only ever
|
||||
// fail (or, before this was locked down, silently succeed with the
|
||||
// well-known fixed dev code).
|
||||
//
|
||||
// emailSignupEnabled accounts fail this even with a real phoneCodeSender:
|
||||
// their "phone" is a synthetic 888-prefixed display number
|
||||
// (domain.NewEmailSignupDisplayPhone), never a real number anyone can
|
||||
// receive SMS on -- email is the actual identity there, regardless of what
|
||||
// SMS infra exists for other (real-phone) accounts on this server.
|
||||
func (s *Service) LoginEmailResetAvailable() bool {
|
||||
return s.phoneCodeSender != nil && !s.emailSignupEnabled
|
||||
return s != nil && s.phoneCodeSender != nil && s.codes != nil && s.users != nil && !s.emailSignupEnabled
|
||||
}
|
||||
|
||||
// ConsumeLoginEmailReset authorizes auth.resetLoginEmail with the exact
|
||||
// email-login hash previously issued for this phone owner. Possession of only
|
||||
// a phone number is never sufficient to remove an authentication factor.
|
||||
func (s *Service) ConsumeLoginEmailReset(ctx context.Context, phone, phoneCodeHash string) (int64, error) {
|
||||
// This flow exists to fall back to an SMS code when the login email is
|
||||
// unreachable. Two independent reasons it must refuse outright, before
|
||||
// ClearLoginEmail runs so nothing is ever mutated on a doomed request:
|
||||
// - no real phoneCodeSender: the "SMS code" is always the well-known
|
||||
// TELESRV_DEV_AUTH_CODE (see createPhoneCode), so anyone who can call
|
||||
// sendCode for a phone (no email access required) could strip the
|
||||
// login-email requirement with a publicly known code.
|
||||
// - emailSignupEnabled: this account's "phone" is a synthetic 888-
|
||||
// prefixed display number (domain.NewEmailSignupDisplayPhone), never
|
||||
// a real number anyone can receive SMS on. Email is the actual
|
||||
// identity here regardless of whether a real SMS sender happens to
|
||||
// be configured for other (real-phone) accounts on this server.
|
||||
if s.phoneCodeSender == nil || s.emailSignupEnabled {
|
||||
// Refuse before consuming the email proof or clearing any account state. If
|
||||
// there is no real SMS sender, the successor code would be the public
|
||||
// development code and could strip the login-email factor.
|
||||
if !s.LoginEmailResetAvailable() || s.codes == nil {
|
||||
return 0, ErrCodeInvalid
|
||||
}
|
||||
phone = normalizePhone(phone)
|
||||
|
|
@ -1488,18 +1485,7 @@ func (s *Service) ResetAuthorization(ctx context.Context, userID, hash int64) (d
|
|||
if revoker, ok := s.auths.(authorizationRevoker); ok {
|
||||
return revoker.RevokeByHash(ctx, userID, hash)
|
||||
}
|
||||
target, found, err := s.authorizationByHash(ctx, userID, hash)
|
||||
if err != nil || !found {
|
||||
return target, found, err
|
||||
}
|
||||
if err := s.deleteAuthKey(ctx, target.AuthKeyID); err != nil {
|
||||
return target, true, err
|
||||
}
|
||||
deleted, found, err := s.auths.DeleteByHash(ctx, userID, hash)
|
||||
if err != nil || !found {
|
||||
return deleted, found, err
|
||||
}
|
||||
return deleted, true, nil
|
||||
return s.auths.DeleteByHash(ctx, userID, hash)
|
||||
}
|
||||
|
||||
func (s *Service) ResetAuthorizations(ctx context.Context, userID int64, keepAuthKeyID [8]byte) ([]domain.Authorization, error) {
|
||||
|
|
@ -1509,54 +1495,7 @@ func (s *Service) ResetAuthorizations(ctx context.Context, userID int64, keepAut
|
|||
if revoker, ok := s.auths.(authorizationRevoker); ok {
|
||||
return revoker.RevokeByUserExcept(ctx, userID, keepAuthKeyID)
|
||||
}
|
||||
targets, err := s.authorizationsByUserExcept(ctx, userID, keepAuthKeyID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, a := range targets {
|
||||
if err := s.deleteAuthKey(ctx, a.AuthKeyID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
deleted, err := s.auths.DeleteByUserExcept(ctx, userID, keepAuthKeyID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return deleted, nil
|
||||
}
|
||||
|
||||
func (s *Service) deleteAuthKey(ctx context.Context, authKeyID [8]byte) error {
|
||||
if s == nil || s.authKeys == nil || authKeyID == ([8]byte{}) {
|
||||
return nil
|
||||
}
|
||||
return s.authKeys.Delete(ctx, authKeyID)
|
||||
}
|
||||
|
||||
func (s *Service) authorizationByHash(ctx context.Context, userID, hash int64) (domain.Authorization, bool, error) {
|
||||
items, err := s.auths.ListByUser(ctx, userID)
|
||||
if err != nil {
|
||||
return domain.Authorization{}, false, err
|
||||
}
|
||||
for _, a := range items {
|
||||
if a.Hash == hash {
|
||||
return a, true, nil
|
||||
}
|
||||
}
|
||||
return domain.Authorization{}, false, nil
|
||||
}
|
||||
|
||||
func (s *Service) authorizationsByUserExcept(ctx context.Context, userID int64, keepAuthKeyID [8]byte) ([]domain.Authorization, error) {
|
||||
items, err := s.auths.ListByUser(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]domain.Authorization, 0, len(items))
|
||||
for _, a := range items {
|
||||
if a.AuthKeyID != keepAuthKeyID {
|
||||
out = append(out, a)
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
return s.auths.DeleteByUserExcept(ctx, userID, keepAuthKeyID)
|
||||
}
|
||||
|
||||
func (s *Service) bind(ctx context.Context, auth domain.Authorization, userID int64) error {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue