in auth/user_mgt.go [953:1035]
func (r *userQueryResponse) makeExportedUserRecord() (*ExportedUserRecord, error) {
var customClaims map[string]interface{}
if r.CustomAttributes != "" {
if err := json.Unmarshal([]byte(r.CustomAttributes), &customClaims); err != nil {
return nil, err
}
if len(customClaims) == 0 {
customClaims = nil
}
}
// If the password hash is redacted (probably due to missing permissions)
// then clear it out, similar to how the salt is returned. (Otherwise, it
// *looks* like a b64-encoded hash is present, which is confusing.)
hash := r.PasswordHash
if hash == b64Redacted {
hash = ""
}
var lastRefreshTimestamp int64
if r.LastRefreshAt != "" {
t, err := time.Parse(time.RFC3339, r.LastRefreshAt)
if err != nil {
return nil, err
}
lastRefreshTimestamp = t.Unix() * 1000
}
// Map the MFA info to a slice of enrolled factors. Currently there is only
// support for PhoneMultiFactorInfo.
var enrolledFactors []*MultiFactorInfo
for _, factor := range r.MFAInfo {
var enrollmentTimestamp int64
if factor.EnrolledAt != "" {
t, err := time.Parse(time.RFC3339, factor.EnrolledAt)
if err != nil {
return nil, err
}
enrollmentTimestamp = t.Unix() * 1000
}
if factor.PhoneInfo == "" {
return nil, fmt.Errorf("unsupported multi-factor auth response: %#v", factor)
}
enrolledFactors = append(enrolledFactors, &MultiFactorInfo{
UID: factor.MFAEnrollmentID,
DisplayName: factor.DisplayName,
EnrollmentTimestamp: enrollmentTimestamp,
FactorID: "phone",
PhoneNumber: factor.PhoneInfo,
})
}
return &ExportedUserRecord{
UserRecord: &UserRecord{
UserInfo: &UserInfo{
DisplayName: r.DisplayName,
Email: r.Email,
PhoneNumber: r.PhoneNumber,
PhotoURL: r.PhotoURL,
UID: r.UID,
ProviderID: defaultProviderID,
},
CustomClaims: customClaims,
Disabled: r.Disabled,
EmailVerified: r.EmailVerified,
ProviderUserInfo: r.ProviderUserInfo,
TenantID: r.TenantID,
TokensValidAfterMillis: r.ValidSinceSeconds * 1000,
UserMetadata: &UserMetadata{
LastLogInTimestamp: r.LastLogInTimestamp,
CreationTimestamp: r.CreationTimestamp,
LastRefreshTimestamp: lastRefreshTimestamp,
},
MultiFactor: &MultiFactorSettings{
EnrolledFactors: enrolledFactors,
},
},
PasswordHash: hash,
PasswordSalt: r.PasswordSalt,
}, nil
}