feat: add im auth verification flows
This commit is contained in:
@@ -3,6 +3,7 @@ package main
|
||||
import (
|
||||
"container/heap"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"slices"
|
||||
@@ -383,6 +384,19 @@ func addCreds(tenantID types.TenantID, uid types.Uid, creds []MsgCredClient, ext
|
||||
continue
|
||||
}
|
||||
|
||||
if cr.Response != "" {
|
||||
if value, ok, err := consumeProductVerificationCred(tenantID, uid, cr, vld.PreCheck); ok || err != nil {
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
validated = append(validated, cr.Method)
|
||||
if globals.validators[cr.Method].addToTags {
|
||||
extraTags = append(extraTags, cr.Method+":"+value)
|
||||
}
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
isNew, err := vld.Request(tenantID, uid, cr.Value, lang, cr.Response, tmpToken)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
@@ -413,6 +427,52 @@ func addCreds(tenantID types.TenantID, uid types.Uid, creds []MsgCredClient, ext
|
||||
return validated, extraTags, nil
|
||||
}
|
||||
|
||||
func consumeProductVerificationCred(tenantID types.TenantID, uid types.Uid, cr *MsgCredClient,
|
||||
preCheck func(string, map[string]any) (string, error)) (string, bool, error) {
|
||||
challengeID, _ := cr.Params["challenge_id"].(string)
|
||||
challengeID = strings.TrimSpace(challengeID)
|
||||
if challengeID == "" {
|
||||
return "", false, nil
|
||||
}
|
||||
if store.Verifications == nil {
|
||||
return "", true, types.ErrInternal
|
||||
}
|
||||
normalized, err := preCheck(cr.Value, cr.Params)
|
||||
if err != nil {
|
||||
return "", true, err
|
||||
}
|
||||
value := strings.TrimPrefix(normalized, cr.Method+":")
|
||||
vc, err := store.Verifications.Get(tenantID, challengeID)
|
||||
if err != nil {
|
||||
return "", true, err
|
||||
}
|
||||
if vc.Scene != "register" || vc.State != types.VerificationStateVerified || vc.PhoneHash == "" {
|
||||
return "", true, types.ErrInvalidResponse
|
||||
}
|
||||
tokenHash := hashIMSecret(tenantID, vc.Scene, vc.ChallengeID, vc.PhoneHash, cr.Response)
|
||||
if vc.VerificationTokenHash == nil || *vc.VerificationTokenHash != tokenHash {
|
||||
return "", true, types.ErrInvalidResponse
|
||||
}
|
||||
now := time.Now().UTC().Round(time.Millisecond)
|
||||
if !now.Before(vc.ExpiresAt) {
|
||||
return "", true, types.ErrExpired
|
||||
}
|
||||
if err := store.Verifications.Consume(tenantID, vc.ChallengeID, tokenHash, now); err != nil {
|
||||
return "", true, err
|
||||
}
|
||||
_, err = store.Users.UpsertCred(tenantID, &types.Credential{
|
||||
ObjHeader: types.ObjHeader{CreatedAt: now, UpdatedAt: now},
|
||||
User: uid.String(),
|
||||
Method: cr.Method,
|
||||
Value: value,
|
||||
Done: true,
|
||||
})
|
||||
if err != nil {
|
||||
return "", true, err
|
||||
}
|
||||
return value, true, nil
|
||||
}
|
||||
|
||||
// validatedCreds returns the list of validated credentials including those validated in this call.
|
||||
// Returns all validated methods including those validated earlier and now.
|
||||
// Returns either a full set of tags or nil for tags if tags are unchanged.
|
||||
|
||||
Reference in New Issue
Block a user