From 824f7afa7666f47efe2127f3a832b539ac68005c Mon Sep 17 00:00:00 2001 From: Pragati Date: Mon, 24 Jul 2023 13:57:29 -0700 Subject: [PATCH 01/11] `PhoneMultiFactorConfig` instead of `PhoneNumber` --- auth/user_mgt.go | 114 +++++++++++++++++++++--------- auth/user_mgt_test.go | 112 +++++++++++++++++++---------- integration/auth/user_mgt_test.go | 14 ++-- messaging/messaging_batch.go | 2 +- testdata/get_user.json | 8 ++- testdata/list_users.json | 36 ++++++---- 6 files changed, 198 insertions(+), 88 deletions(-) diff --git a/auth/user_mgt.go b/auth/user_mgt.go index fe6ac986..96efd545 100644 --- a/auth/user_mgt.go +++ b/auth/user_mgt.go @@ -42,6 +42,7 @@ const ( createUserMethod = "createUser" updateUserMethod = "updateUser" phoneMultiFactorID = "phone" + totpMultiFactorID = "totp" ) // 'REDACTED', encoded as a base64 string. @@ -62,20 +63,37 @@ type UserInfo struct { // multiFactorInfoResponse describes the `mfaInfo` of the user record API response type multiFactorInfoResponse struct { - MFAEnrollmentID string `json:"mfaEnrollmentId,omitempty"` - DisplayName string `json:"displayName,omitempty"` - PhoneInfo string `json:"phoneInfo,omitempty"` - EnrolledAt string `json:"enrolledAt,omitempty"` + MFAEnrollmentID string `json:"mfaEnrollmentId,omitempty"` + DisplayName string `json:"displayName,omitempty"` + PhoneInfo string `json:"phoneInfo,omitempty"` + TOTPInfo *TOTPInfo `json:"totpInfo,omitempty"` + EnrolledAt string `json:"enrolledAt,omitempty"` +} + +// TOTPInfo describes a server side user enrolled second totp factor. +type TOTPInfo struct{} + +// PhoneMultiFactorInfo describes a user enrolled second phone factor. +type PhoneMultiFactorInfo struct { + PhoneNumber string +} + +// TOTPMultiFactorInfo describes a user enrolled second totp factor. +type TOTPMultiFactorInfo struct{} + +type multiFactorEnrollments struct { + Enrollments []*multiFactorInfoResponse `json:"enrollments"` } // MultiFactorInfo describes a user enrolled second phone factor. -// TODO : convert PhoneNumber to PhoneMultiFactorInfo struct type MultiFactorInfo struct { - UID string - DisplayName string - EnrollmentTimestamp int64 - FactorID string - PhoneNumber string + UID string + DisplayName string + EnrollmentTimestamp int64 + FactorID string + PhoneNumber string `Deprecated:"Use PhoneMultiFactorInfo instead"` + PhoneMultiFactorInfo *PhoneMultiFactorInfo + TOTPMultiFactorInfo *TOTPMultiFactorInfo } // MultiFactorSettings describes the multi-factor related user settings. @@ -166,18 +184,25 @@ func (u *UserToCreate) set(key string, value interface{}) *UserToCreate { // Converts a client format second factor object to server format. func convertMultiFactorInfoToServerFormat(mfaInfo MultiFactorInfo) (multiFactorInfoResponse, error) { - var authFactorInfo multiFactorInfoResponse + authFactorInfo := multiFactorInfoResponse{DisplayName: mfaInfo.DisplayName} if mfaInfo.EnrollmentTimestamp != 0 { authFactorInfo.EnrolledAt = time.Unix(mfaInfo.EnrollmentTimestamp, 0).Format("2006-01-02T15:04:05Z07:00Z") } - if mfaInfo.FactorID == phoneMultiFactorID { - authFactorInfo.PhoneInfo = mfaInfo.PhoneNumber - authFactorInfo.DisplayName = mfaInfo.DisplayName + if mfaInfo.UID != "" { authFactorInfo.MFAEnrollmentID = mfaInfo.UID - return authFactorInfo, nil } - out, _ := json.Marshal(mfaInfo) - return multiFactorInfoResponse{}, fmt.Errorf("Unsupported second factor %s provided", string(out)) + authFactorInfo.MFAEnrollmentID = mfaInfo.UID + + switch mfaInfo.FactorID { + case phoneMultiFactorID: + authFactorInfo.PhoneInfo = mfaInfo.PhoneMultiFactorInfo.PhoneNumber + case totpMultiFactorID: + authFactorInfo.TOTPInfo = (*TOTPInfo)(mfaInfo.TOTPMultiFactorInfo) + default: + out, _ := json.Marshal(mfaInfo) + return multiFactorInfoResponse{}, fmt.Errorf("unsupported second factor %s provided", string(out)) + } + return authFactorInfo, nil } func (u *UserToCreate) validatedRequest() (map[string]interface{}, error) { @@ -333,7 +358,8 @@ func (u *UserToUpdate) validatedRequest() (map[string]interface{}, error) { if err != nil { return nil, err } - req["mfaInfo"] = mfaInfo + // Request body ref: https://cloud.google.com/identity-platform/docs/reference/rest/v1/accounts/update + req["mfa"] = multiFactorEnrollments{mfaInfo} } else { req[k] = v } @@ -665,9 +691,6 @@ func validateAndFormatMfaSettings(mfaSettings MultiFactorSettings, methodType st return nil, fmt.Errorf("\"uid\" is not supported when adding second factors via \"createUser()\"") } case updateUserMethod: - if multiFactorInfo.UID == "" { - return nil, fmt.Errorf("the second factor \"uid\" must be a valid non-empty string when adding second factors via \"updateUser()\"") - } default: return nil, fmt.Errorf("unsupported methodType: %s", methodType) } @@ -675,8 +698,25 @@ func validateAndFormatMfaSettings(mfaSettings MultiFactorSettings, methodType st return nil, fmt.Errorf("the second factor \"displayName\" for \"%s\" must be a valid non-empty string", multiFactorInfo.DisplayName) } if multiFactorInfo.FactorID == phoneMultiFactorID { - if err := validatePhone(multiFactorInfo.PhoneNumber); err != nil { - return nil, fmt.Errorf("the second factor \"phoneNumber\" for \"%s\" must be a non-empty E.164 standard compliant identifier string", multiFactorInfo.PhoneNumber) + if multiFactorInfo.PhoneMultiFactorInfo != nil { + // If PhoneMultiFactorInfo is provided, validate its PhoneNumber field + if err := validatePhone(multiFactorInfo.PhoneMultiFactorInfo.PhoneNumber); err != nil { + return nil, fmt.Errorf("the second factor \"phoneNumber\" for \"%s\" must be a non-empty E.164 standard compliant identifier string", multiFactorInfo.PhoneMultiFactorInfo.PhoneNumber) + } + // No need for the else here since we are returning from the function + } else if multiFactorInfo.PhoneNumber != "" { + // PhoneMultiFactorInfo is nil, check the deprecated PhoneNumber field + if err := validatePhone(multiFactorInfo.PhoneNumber); err != nil { + return nil, fmt.Errorf("the second factor \"phoneNumber\" for \"%s\" must be a non-empty E.164 standard compliant identifier string", multiFactorInfo.PhoneNumber) + } + // The PhoneNumber field is deprecated, set it in PhoneMultiFactorInfo and inform about the deprecation. + multiFactorInfo.PhoneMultiFactorInfo = &PhoneMultiFactorInfo{ + PhoneNumber: multiFactorInfo.PhoneNumber, + } + fmt.Println("`PhoneNumber` is deprecated, use `PhoneMultiFactorInfo` instead") + } else { + // Both PhoneMultiFactorInfo and deprecated PhoneNumber are missing. + return nil, fmt.Errorf("\"PhoneMultiFactorInfo\" must be defined") } } obj, err := convertMultiFactorInfoToServerFormat(*multiFactorInfo) @@ -1075,17 +1115,27 @@ func (r *userQueryResponse) makeExportedUserRecord() (*ExportedUserRecord, error enrollmentTimestamp = t.Unix() * 1000 } - if factor.PhoneInfo == "" { + if factor.PhoneInfo != "" { + enrolledFactors = append(enrolledFactors, &MultiFactorInfo{ + UID: factor.MFAEnrollmentID, + DisplayName: factor.DisplayName, + EnrollmentTimestamp: enrollmentTimestamp, + FactorID: phoneMultiFactorID, + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: factor.PhoneInfo, + }, + }) + } else if factor.TOTPInfo != nil { + enrolledFactors = append(enrolledFactors, &MultiFactorInfo{ + UID: factor.MFAEnrollmentID, + DisplayName: factor.DisplayName, + EnrollmentTimestamp: enrollmentTimestamp, + FactorID: totpMultiFactorID, + TOTPMultiFactorInfo: &TOTPMultiFactorInfo{}, + }) + } else { return nil, fmt.Errorf("unsupported multi-factor auth response: %#v", factor) } - - enrolledFactors = append(enrolledFactors, &MultiFactorInfo{ - UID: factor.MFAEnrollmentID, - DisplayName: factor.DisplayName, - EnrollmentTimestamp: enrollmentTimestamp, - FactorID: phoneMultiFactorID, - PhoneNumber: factor.PhoneInfo, - }) } return &ExportedUserRecord{ diff --git a/auth/user_mgt_test.go b/auth/user_mgt_test.go index 943810cd..9ad64604 100644 --- a/auth/user_mgt_test.go +++ b/auth/user_mgt_test.go @@ -69,11 +69,20 @@ var testUser = &UserRecord{ MultiFactor: &MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - UID: "0aaded3f-5e73-461d-aef9-37b48e3769be", + UID: "enrolledPhoneFactor", FactorID: "phone", EnrollmentTimestamp: 1614776780000, - PhoneNumber: "+1234567890", - DisplayName: "My MFA Phone", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+1234567890", + }, + DisplayName: "My MFA Phone", + }, + { + UID: "enrolledTOTPFactor", + FactorID: "totp", + EnrollmentTimestamp: 1614776780000, + TOTPMultiFactorInfo: &TOTPMultiFactorInfo{}, + DisplayName: "My MFA TOTP", }, }, }, @@ -646,8 +655,10 @@ func TestInvalidCreateUser(t *testing.T) { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - UID: "EnrollmentID", - PhoneNumber: "+11234567890", + UID: "EnrollmentID", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, DisplayName: "Spouse's phone number", FactorID: "phone", }, @@ -658,7 +669,9 @@ func TestInvalidCreateUser(t *testing.T) { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneNumber: "invalid", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "invalid", + }, DisplayName: "Spouse's phone number", FactorID: "phone", }, @@ -669,7 +682,9 @@ func TestInvalidCreateUser(t *testing.T) { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneNumber: "+11234567890", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, DisplayName: "Spouse's phone number", FactorID: "phone", EnrollmentTimestamp: time.Now().UTC().Unix(), @@ -681,7 +696,9 @@ func TestInvalidCreateUser(t *testing.T) { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneNumber: "+11234567890", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, DisplayName: "Spouse's phone number", FactorID: "", }, @@ -692,8 +709,10 @@ func TestInvalidCreateUser(t *testing.T) { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneNumber: "+11234567890", - FactorID: "phone", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, + FactorID: "phone", }, }, }), @@ -773,7 +792,9 @@ var createUserCases = []struct { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneNumber: "+11234567890", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, DisplayName: "Spouse's phone number", FactorID: "phone", }, @@ -790,12 +811,16 @@ var createUserCases = []struct { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneNumber: "+11234567890", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, DisplayName: "number1", FactorID: "phone", }, { - PhoneNumber: "+11234567890", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, DisplayName: "number2", FactorID: "phone", }, @@ -875,9 +900,11 @@ func TestInvalidUpdateUser(t *testing.T) { (&UserToUpdate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - UID: "enrolledSecondFactor1", - PhoneNumber: "+11234567890", - FactorID: "phone", + UID: "enrolledSecondFactor1", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, + FactorID: "phone", }, }, }), @@ -886,25 +913,16 @@ func TestInvalidUpdateUser(t *testing.T) { (&UserToUpdate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - UID: "enrolledSecondFactor1", - PhoneNumber: "invalid", + UID: "enrolledSecondFactor1", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "invalid", + }, DisplayName: "Spouse's phone number", FactorID: "phone", }, }, }), `the second factor "phoneNumber" for "invalid" must be a non-empty E.164 standard compliant identifier string`, - }, { - (&UserToUpdate{}).MFASettings(MultiFactorSettings{ - EnrolledFactors: []*MultiFactorInfo{ - { - PhoneNumber: "+11234567890", - FactorID: "phone", - DisplayName: "Spouse's phone number", - }, - }, - }), - `the second factor "uid" must be a valid non-empty string when adding second factors via "updateUser()"`, }, { (&UserToUpdate{}).ProviderToLink(&UserProvider{UID: "google_uid"}), "user provider must specify a provider ID", @@ -1049,20 +1067,30 @@ var updateUserCases = []struct { (&UserToUpdate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - UID: "enrolledSecondFactor1", - PhoneNumber: "+11234567890", + UID: "enrolledSecondFactor1", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, DisplayName: "Spouse's phone number", FactorID: "phone", EnrollmentTimestamp: time.Now().Unix(), }, { - UID: "enrolledSecondFactor2", - PhoneNumber: "+11234567890", + UID: "enrolledSecondFactor2", + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, + DisplayName: "Spouse's phone number", + FactorID: "phone", + }, { + PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, DisplayName: "Spouse's phone number", FactorID: "phone", }, }, }), - map[string]interface{}{"mfaInfo": []*multiFactorInfoResponse{ + map[string]interface{}{"mfa": multiFactorEnrollments{Enrollments: []*multiFactorInfoResponse{ { MFAEnrollmentID: "enrolledSecondFactor1", PhoneInfo: "+11234567890", @@ -1074,12 +1102,16 @@ var updateUserCases = []struct { DisplayName: "Spouse's phone number", PhoneInfo: "+11234567890", }, - }, + { + DisplayName: "Spouse's phone number", + PhoneInfo: "+11234567890", + }, + }}, }, }, { (&UserToUpdate{}).MFASettings(MultiFactorSettings{}), - map[string]interface{}{"mfaInfo": nil}, + map[string]interface{}{"mfa": multiFactorEnrollments{Enrollments: nil}}, }, { (&UserToUpdate{}).ProviderToLink(&UserProvider{ @@ -1886,10 +1918,16 @@ func TestMakeExportedUser(t *testing.T) { MFAInfo: []*multiFactorInfoResponse{ { PhoneInfo: "+1234567890", - MFAEnrollmentID: "0aaded3f-5e73-461d-aef9-37b48e3769be", + MFAEnrollmentID: "enrolledPhoneFactor", DisplayName: "My MFA Phone", EnrolledAt: "2021-03-03T13:06:20.542896Z", }, + { + TOTPInfo: &TOTPInfo{}, + MFAEnrollmentID: "enrolledTOTPFactor", + DisplayName: "My MFA TOTP", + EnrolledAt: "2021-03-03T13:06:20.542896Z", + }, }, } diff --git a/integration/auth/user_mgt_test.go b/integration/auth/user_mgt_test.go index c1301f6d..6f43224c 100644 --- a/integration/auth/user_mgt_test.go +++ b/integration/auth/user_mgt_test.go @@ -434,7 +434,9 @@ func TestCreateUserMFA(t *testing.T) { tc.MFASettings(auth.MultiFactorSettings{ EnrolledFactors: []*auth.MultiFactorInfo{ { - PhoneNumber: "+11234567890", + PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, DisplayName: "Spouse's phone number", FactorID: "phone", }, @@ -447,10 +449,12 @@ func TestCreateUserMFA(t *testing.T) { defer deleteUser(user.UID) var factor []*auth.MultiFactorInfo = []*auth.MultiFactorInfo{ { - UID: user.MultiFactor.EnrolledFactors[0].UID, - DisplayName: "Spouse's phone number", - FactorID: "phone", - PhoneNumber: "+11234567890", + UID: user.MultiFactor.EnrolledFactors[0].UID, + DisplayName: "Spouse's phone number", + FactorID: "phone", + PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, EnrollmentTimestamp: user.MultiFactor.EnrolledFactors[0].EnrollmentTimestamp, }, } diff --git a/messaging/messaging_batch.go b/messaging/messaging_batch.go index c8ed63fa..536227d8 100644 --- a/messaging/messaging_batch.go +++ b/messaging/messaging_batch.go @@ -116,7 +116,7 @@ func (c *fcmClient) SendEachDryRun(ctx context.Context, messages []*Message) (*B return c.sendEachInBatch(ctx, messages, true) } -// SendEachForMulticast sends the given multicast message to all the FCM registration tokens specified. +// SendMulticast sends the given multicast message to all the FCM registration tokens specified. // // The tokens array in MulticastMessage may contain up to 500 tokens. SendMulticast uses the // SendEach() function to send the given message to all the target recipients. The diff --git a/testdata/get_user.json b/testdata/get_user.json index a2cac48b..0bf86f95 100644 --- a/testdata/get_user.json +++ b/testdata/get_user.json @@ -35,9 +35,15 @@ "mfaInfo": [ { "phoneInfo": "+1234567890", - "mfaEnrollmentId": "0aaded3f-5e73-461d-aef9-37b48e3769be", + "mfaEnrollmentId": "enrolledPhoneFactor", "displayName": "My MFA Phone", "enrolledAt": "2021-03-03T13:06:20.542896Z" + }, + { + "totpInfo": {}, + "mfaEnrollmentId": "enrolledTOTPFactor", + "displayName": "My MFA TOTP", + "enrolledAt": "2021-03-03T13:06:20.542896Z" } ] } diff --git a/testdata/list_users.json b/testdata/list_users.json index bf94ff49..2b630686 100644 --- a/testdata/list_users.json +++ b/testdata/list_users.json @@ -33,12 +33,18 @@ "customAttributes": "{\"admin\": true, \"package\": \"gold\"}", "tenantId": "testTenant", "mfaInfo": [ - { - "phoneInfo": "+1234567890", - "mfaEnrollmentId": "0aaded3f-5e73-461d-aef9-37b48e3769be", - "displayName": "My MFA Phone", - "enrolledAt": "2021-03-03T13:06:20.542896Z" - } + { + "phoneInfo": "+1234567890", + "mfaEnrollmentId": "enrolledPhoneFactor", + "displayName": "My MFA Phone", + "enrolledAt": "2021-03-03T13:06:20.542896Z" + }, + { + "totpInfo": {}, + "mfaEnrollmentId": "enrolledTOTPFactor", + "displayName": "My MFA TOTP", + "enrolledAt": "2021-03-03T13:06:20.542896Z" + } ] }, { @@ -73,12 +79,18 @@ "customAttributes": "{\"admin\": true, \"package\": \"gold\"}", "tenantId": "testTenant", "mfaInfo": [ - { - "phoneInfo": "+1234567890", - "mfaEnrollmentId": "0aaded3f-5e73-461d-aef9-37b48e3769be", - "displayName": "My MFA Phone", - "enrolledAt": "2021-03-03T13:06:20.542896Z" - } + { + "phoneInfo": "+1234567890", + "mfaEnrollmentId": "enrolledPhoneFactor", + "displayName": "My MFA Phone", + "enrolledAt": "2021-03-03T13:06:20.542896Z" + }, + { + "totpInfo": {}, + "mfaEnrollmentId": "enrolledTOTPFactor", + "displayName": "My MFA TOTP", + "enrolledAt": "2021-03-03T13:06:20.542896Z" + } ] }, { From dcfe84f41f66edfe9c30a993a36a38d48eed14c7 Mon Sep 17 00:00:00 2001 From: Pragati Date: Mon, 24 Jul 2023 13:59:08 -0700 Subject: [PATCH 02/11] Undo messaging_batch changes --- messaging/messaging_batch.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messaging/messaging_batch.go b/messaging/messaging_batch.go index 536227d8..c8ed63fa 100644 --- a/messaging/messaging_batch.go +++ b/messaging/messaging_batch.go @@ -116,7 +116,7 @@ func (c *fcmClient) SendEachDryRun(ctx context.Context, messages []*Message) (*B return c.sendEachInBatch(ctx, messages, true) } -// SendMulticast sends the given multicast message to all the FCM registration tokens specified. +// SendEachForMulticast sends the given multicast message to all the FCM registration tokens specified. // // The tokens array in MulticastMessage may contain up to 500 tokens. SendMulticast uses the // SendEach() function to send the given message to all the target recipients. The From 56b43f35377489860bc60a400b0a5b4e9f47a4f7 Mon Sep 17 00:00:00 2001 From: Pragati Date: Mon, 24 Jul 2023 14:11:29 -0700 Subject: [PATCH 03/11] deprecated comment for `PhoneNumber` field --- auth/user_mgt.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/user_mgt.go b/auth/user_mgt.go index 96efd545..ed893c57 100644 --- a/auth/user_mgt.go +++ b/auth/user_mgt.go @@ -91,7 +91,7 @@ type MultiFactorInfo struct { DisplayName string EnrollmentTimestamp int64 FactorID string - PhoneNumber string `Deprecated:"Use PhoneMultiFactorInfo instead"` + PhoneNumber string // Deprecated: Use PhoneMultiFactorInfo instead PhoneMultiFactorInfo *PhoneMultiFactorInfo TOTPMultiFactorInfo *TOTPMultiFactorInfo } From e6d19a88b44133104f238ce199103433882bfa61 Mon Sep 17 00:00:00 2001 From: Pragati Date: Mon, 24 Jul 2023 17:31:25 -0700 Subject: [PATCH 04/11] Add tests for `PhoneNumber` integration check --- auth/user_mgt_test.go | 13 +++++++++++-- integration/auth/user_mgt_test.go | 26 +++++++++++++++++++++----- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/auth/user_mgt_test.go b/auth/user_mgt_test.go index 9ad64604..e71df136 100644 --- a/auth/user_mgt_test.go +++ b/auth/user_mgt_test.go @@ -795,7 +795,12 @@ var createUserCases = []struct { PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, - DisplayName: "Spouse's phone number", + DisplayName: "Phone Number active", + FactorID: "phone", + }, + { + PhoneNumber: "+11234567890", + DisplayName: "Phone Number deprecated", FactorID: "phone", }, }, @@ -803,7 +808,11 @@ var createUserCases = []struct { map[string]interface{}{"mfaInfo": []*multiFactorInfoResponse{ { PhoneInfo: "+11234567890", - DisplayName: "Spouse's phone number", + DisplayName: "Phone Number active", + }, + { + PhoneInfo: "+11234567890", + DisplayName: "Phone Number deprecated", }, }, }, diff --git a/integration/auth/user_mgt_test.go b/integration/auth/user_mgt_test.go index 6f43224c..96453581 100644 --- a/integration/auth/user_mgt_test.go +++ b/integration/auth/user_mgt_test.go @@ -30,6 +30,7 @@ import ( "firebase.google.com/go/v4/auth" "firebase.google.com/go/v4/auth/hash" + "github.com/google/go-cmp/cmp" "google.golang.org/api/iterator" ) @@ -433,11 +434,16 @@ func TestCreateUserMFA(t *testing.T) { tc.EmailVerified(true) tc.MFASettings(auth.MultiFactorSettings{ EnrolledFactors: []*auth.MultiFactorInfo{ + { + PhoneNumber: "+11234567890", + DisplayName: "Phone Number deprecated", + FactorID: "phone", + }, { PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ - PhoneNumber: "+11234567890", + PhoneNumber: "+19876543210", }, - DisplayName: "Spouse's phone number", + DisplayName: "Phone Number active", FactorID: "phone", }, }, @@ -447,16 +453,25 @@ func TestCreateUserMFA(t *testing.T) { t.Fatalf("CreateUser() = %v; want = nil", err) } defer deleteUser(user.UID) - var factor []*auth.MultiFactorInfo = []*auth.MultiFactorInfo{ + var factors []*auth.MultiFactorInfo = []*auth.MultiFactorInfo{ { UID: user.MultiFactor.EnrolledFactors[0].UID, - DisplayName: "Spouse's phone number", + DisplayName: "Phone Number deprecated", FactorID: "phone", PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, EnrollmentTimestamp: user.MultiFactor.EnrolledFactors[0].EnrollmentTimestamp, }, + { + UID: user.MultiFactor.EnrolledFactors[1].UID, + DisplayName: "Phone Number active", + FactorID: "phone", + PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + PhoneNumber: "+19876543210", + }, + EnrollmentTimestamp: user.MultiFactor.EnrolledFactors[1].EnrollmentTimestamp, + }, } want := auth.UserRecord{ EmailVerified: true, @@ -470,10 +485,11 @@ func TestCreateUserMFA(t *testing.T) { }, TokensValidAfterMillis: user.TokensValidAfterMillis, MultiFactor: &auth.MultiFactorSettings{ - EnrolledFactors: factor, + EnrolledFactors: factors, }, } if !reflect.DeepEqual(*user, want) { + fmt.Println(cmp.Diff(*user, want)) t.Errorf("CreateUser() = %#v; want = %#v", *user, want) } } From 437d1a8af20dd3568c56527388fb7b47e0f7c701 Mon Sep 17 00:00:00 2001 From: Pragati Date: Fri, 28 Jul 2023 13:58:58 -0700 Subject: [PATCH 05/11] Keeping `PhoneNumber` in fetched `UserInfo` to avoid breaking changes --- auth/user_mgt.go | 2 +- auth/user_mgt_test.go | 3 + integration/auth/user_mgt_test.go | 113 +++++++++++++++++++++++++++++- 3 files changed, 115 insertions(+), 3 deletions(-) diff --git a/auth/user_mgt.go b/auth/user_mgt.go index ed893c57..197a6e94 100644 --- a/auth/user_mgt.go +++ b/auth/user_mgt.go @@ -713,7 +713,6 @@ func validateAndFormatMfaSettings(mfaSettings MultiFactorSettings, methodType st multiFactorInfo.PhoneMultiFactorInfo = &PhoneMultiFactorInfo{ PhoneNumber: multiFactorInfo.PhoneNumber, } - fmt.Println("`PhoneNumber` is deprecated, use `PhoneMultiFactorInfo` instead") } else { // Both PhoneMultiFactorInfo and deprecated PhoneNumber are missing. return nil, fmt.Errorf("\"PhoneMultiFactorInfo\" must be defined") @@ -1121,6 +1120,7 @@ func (r *userQueryResponse) makeExportedUserRecord() (*ExportedUserRecord, error DisplayName: factor.DisplayName, EnrollmentTimestamp: enrollmentTimestamp, FactorID: phoneMultiFactorID, + PhoneNumber: factor.PhoneInfo, PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ PhoneNumber: factor.PhoneInfo, }, diff --git a/auth/user_mgt_test.go b/auth/user_mgt_test.go index e71df136..0f227d69 100644 --- a/auth/user_mgt_test.go +++ b/auth/user_mgt_test.go @@ -75,6 +75,7 @@ var testUser = &UserRecord{ PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ PhoneNumber: "+1234567890", }, + PhoneNumber: "+1234567890", DisplayName: "My MFA Phone", }, { @@ -1088,12 +1089,14 @@ var updateUserCases = []struct { PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, + PhoneNumber: "+11234567890", DisplayName: "Spouse's phone number", FactorID: "phone", }, { PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, + PhoneNumber: "+11234567890", DisplayName: "Spouse's phone number", FactorID: "phone", }, diff --git a/integration/auth/user_mgt_test.go b/integration/auth/user_mgt_test.go index 96453581..cee8650e 100644 --- a/integration/auth/user_mgt_test.go +++ b/integration/auth/user_mgt_test.go @@ -30,7 +30,6 @@ import ( "firebase.google.com/go/v4/auth" "firebase.google.com/go/v4/auth/hash" - "github.com/google/go-cmp/cmp" "google.golang.org/api/iterator" ) @@ -461,6 +460,7 @@ func TestCreateUserMFA(t *testing.T) { PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, + PhoneNumber: "+11234567890", EnrollmentTimestamp: user.MultiFactor.EnrolledFactors[0].EnrollmentTimestamp, }, { @@ -470,6 +470,7 @@ func TestCreateUserMFA(t *testing.T) { PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+19876543210", }, + PhoneNumber: "+19876543210", EnrollmentTimestamp: user.MultiFactor.EnrolledFactors[1].EnrollmentTimestamp, }, } @@ -489,7 +490,6 @@ func TestCreateUserMFA(t *testing.T) { }, } if !reflect.DeepEqual(*user, want) { - fmt.Println(cmp.Diff(*user, want)) t.Errorf("CreateUser() = %#v; want = %#v", *user, want) } } @@ -730,6 +730,115 @@ func TestUpdateUser(t *testing.T) { }) } +func TestUpdateUserMFA(t *testing.T) { + // Creates a new user for testing purposes. The user's uid will be + // '$name_$tenRandomChars' and email will be + // '$name_$tenRandomChars@example.com'. + createTestUserWithMFA := func(name string) *auth.UserRecord { + // TODO(rsgowman: This function could usefully be employed throughout + // this file. + tenRandomChars := generateRandomAlphaNumericString(10) + userRecord, err := client.CreateUser(context.Background(), + (&auth.UserToCreate{}). + Email(name+"_"+tenRandomChars+"@example.com"). + EmailVerified(true). + MFASettings(auth.MultiFactorSettings{ + EnrolledFactors: []*auth.MultiFactorInfo{ + { + PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, + DisplayName: "Phone Number active", + FactorID: "phone", + }, + { + PhoneNumber: "+19876543210", + DisplayName: "Phone Number deprecated", + FactorID: "phone", + }, + }, + }), + ) + if err != nil { + t.Fatal(err) + } + return userRecord + } + // Create a test user with MFA settings for testing + user := createTestUserWithMFA("UpdateUserMFA") + defer deleteUser(user.UID) + + // Define the updated MFA factors + updatedFactors := []*auth.MultiFactorInfo{ + { + UID: user.MultiFactor.EnrolledFactors[0].UID, + DisplayName: "Phone Number active updated", + FactorID: "phone", + PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, + }, + { + UID: user.MultiFactor.EnrolledFactors[1].UID, + DisplayName: "Phone Number deprecated updated", + FactorID: "phone", + PhoneNumber: "+19876543210", + }, + } + + // Update the MFA settings + params := (&auth.UserToUpdate{}).MFASettings(auth.MultiFactorSettings{ + EnrolledFactors: updatedFactors, + }) + + updatedUser, err := client.UpdateUser(context.Background(), user.UID, params) + if err != nil { + t.Fatal(err) + } + + want := auth.UserRecord{ + EmailVerified: true, + UserInfo: &auth.UserInfo{ + Email: user.Email, + UID: user.UID, + ProviderID: "firebase", + }, + UserMetadata: &auth.UserMetadata{ + CreationTimestamp: user.UserMetadata.CreationTimestamp, + }, + TokensValidAfterMillis: user.TokensValidAfterMillis, + MultiFactor: &auth.MultiFactorSettings{ + EnrolledFactors: []*auth.MultiFactorInfo{ + { + UID: user.MultiFactor.EnrolledFactors[0].UID, + PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + PhoneNumber: "+11234567890", + }, + PhoneNumber: "+11234567890", + DisplayName: "Phone Number active updated", + FactorID: "phone", + EnrollmentTimestamp: user.MultiFactor.EnrolledFactors[0].EnrollmentTimestamp, + }, + { + UID: user.MultiFactor.EnrolledFactors[1].UID, + PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + PhoneNumber: "+19876543210", + }, + PhoneNumber: "+19876543210", + DisplayName: "Phone Number deprecated updated", + FactorID: "phone", + EnrollmentTimestamp: user.MultiFactor.EnrolledFactors[1].EnrollmentTimestamp, + }, + }, + }, + } + + // Compare the updated user with the expected user record + if !reflect.DeepEqual(*updatedUser, want) { + t.Errorf("UpdateUser() = %#v; want = %#v", *updatedUser, want) + } +} + func TestDisableUser(t *testing.T) { user := newUserWithParams(t) defer deleteUser(user.UID) From 15a86512dbded63470f07f6055b2535855dc8fc1 Mon Sep 17 00:00:00 2001 From: Pragati Date: Fri, 28 Jul 2023 14:08:08 -0700 Subject: [PATCH 06/11] updated user settings --- integration/auth/user_mgt_test.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/integration/auth/user_mgt_test.go b/integration/auth/user_mgt_test.go index cee8650e..8b79ab4f 100644 --- a/integration/auth/user_mgt_test.go +++ b/integration/auth/user_mgt_test.go @@ -771,7 +771,6 @@ func TestUpdateUserMFA(t *testing.T) { // Define the updated MFA factors updatedFactors := []*auth.MultiFactorInfo{ { - UID: user.MultiFactor.EnrolledFactors[0].UID, DisplayName: "Phone Number active updated", FactorID: "phone", PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ @@ -779,7 +778,6 @@ func TestUpdateUserMFA(t *testing.T) { }, }, { - UID: user.MultiFactor.EnrolledFactors[1].UID, DisplayName: "Phone Number deprecated updated", FactorID: "phone", PhoneNumber: "+19876543210", @@ -799,35 +797,35 @@ func TestUpdateUserMFA(t *testing.T) { want := auth.UserRecord{ EmailVerified: true, UserInfo: &auth.UserInfo{ - Email: user.Email, - UID: user.UID, + Email: updatedUser.Email, + UID: updatedUser.UID, ProviderID: "firebase", }, UserMetadata: &auth.UserMetadata{ - CreationTimestamp: user.UserMetadata.CreationTimestamp, + CreationTimestamp: updatedUser.UserMetadata.CreationTimestamp, }, - TokensValidAfterMillis: user.TokensValidAfterMillis, + TokensValidAfterMillis: updatedUser.TokensValidAfterMillis, MultiFactor: &auth.MultiFactorSettings{ EnrolledFactors: []*auth.MultiFactorInfo{ { - UID: user.MultiFactor.EnrolledFactors[0].UID, + UID: updatedUser.MultiFactor.EnrolledFactors[0].UID, PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, PhoneNumber: "+11234567890", DisplayName: "Phone Number active updated", FactorID: "phone", - EnrollmentTimestamp: user.MultiFactor.EnrolledFactors[0].EnrollmentTimestamp, + EnrollmentTimestamp: updatedUser.MultiFactor.EnrolledFactors[0].EnrollmentTimestamp, }, { - UID: user.MultiFactor.EnrolledFactors[1].UID, + UID: updatedUser.MultiFactor.EnrolledFactors[1].UID, PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+19876543210", }, PhoneNumber: "+19876543210", DisplayName: "Phone Number deprecated updated", FactorID: "phone", - EnrollmentTimestamp: user.MultiFactor.EnrolledFactors[1].EnrollmentTimestamp, + EnrollmentTimestamp: updatedUser.MultiFactor.EnrolledFactors[1].EnrollmentTimestamp, }, }, }, From 0eecfa85984fd80409568228627cf14ffa140de9 Mon Sep 17 00:00:00 2001 From: Pragati Date: Mon, 7 Aug 2023 15:38:57 -0700 Subject: [PATCH 07/11] Update variable names --- auth/user_mgt.go | 30 +++++++++++++++--------------- auth/user_mgt_test.go | 30 +++++++++++++++--------------- integration/auth/user_mgt_test.go | 14 +++++++------- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/auth/user_mgt.go b/auth/user_mgt.go index 197a6e94..a25593b5 100644 --- a/auth/user_mgt.go +++ b/auth/user_mgt.go @@ -87,13 +87,13 @@ type multiFactorEnrollments struct { // MultiFactorInfo describes a user enrolled second phone factor. type MultiFactorInfo struct { - UID string - DisplayName string - EnrollmentTimestamp int64 - FactorID string - PhoneNumber string // Deprecated: Use PhoneMultiFactorInfo instead - PhoneMultiFactorInfo *PhoneMultiFactorInfo - TOTPMultiFactorInfo *TOTPMultiFactorInfo + UID string + DisplayName string + EnrollmentTimestamp int64 + FactorID string + PhoneNumber string // Deprecated: Use PhoneMultiFactorInfo instead + Phone *PhoneMultiFactorInfo + TOTP *TOTPMultiFactorInfo } // MultiFactorSettings describes the multi-factor related user settings. @@ -195,9 +195,9 @@ func convertMultiFactorInfoToServerFormat(mfaInfo MultiFactorInfo) (multiFactorI switch mfaInfo.FactorID { case phoneMultiFactorID: - authFactorInfo.PhoneInfo = mfaInfo.PhoneMultiFactorInfo.PhoneNumber + authFactorInfo.PhoneInfo = mfaInfo.Phone.PhoneNumber case totpMultiFactorID: - authFactorInfo.TOTPInfo = (*TOTPInfo)(mfaInfo.TOTPMultiFactorInfo) + authFactorInfo.TOTPInfo = (*TOTPInfo)(mfaInfo.TOTP) default: out, _ := json.Marshal(mfaInfo) return multiFactorInfoResponse{}, fmt.Errorf("unsupported second factor %s provided", string(out)) @@ -698,10 +698,10 @@ func validateAndFormatMfaSettings(mfaSettings MultiFactorSettings, methodType st return nil, fmt.Errorf("the second factor \"displayName\" for \"%s\" must be a valid non-empty string", multiFactorInfo.DisplayName) } if multiFactorInfo.FactorID == phoneMultiFactorID { - if multiFactorInfo.PhoneMultiFactorInfo != nil { + if multiFactorInfo.Phone != nil { // If PhoneMultiFactorInfo is provided, validate its PhoneNumber field - if err := validatePhone(multiFactorInfo.PhoneMultiFactorInfo.PhoneNumber); err != nil { - return nil, fmt.Errorf("the second factor \"phoneNumber\" for \"%s\" must be a non-empty E.164 standard compliant identifier string", multiFactorInfo.PhoneMultiFactorInfo.PhoneNumber) + if err := validatePhone(multiFactorInfo.Phone.PhoneNumber); err != nil { + return nil, fmt.Errorf("the second factor \"phoneNumber\" for \"%s\" must be a non-empty E.164 standard compliant identifier string", multiFactorInfo.Phone.PhoneNumber) } // No need for the else here since we are returning from the function } else if multiFactorInfo.PhoneNumber != "" { @@ -710,7 +710,7 @@ func validateAndFormatMfaSettings(mfaSettings MultiFactorSettings, methodType st return nil, fmt.Errorf("the second factor \"phoneNumber\" for \"%s\" must be a non-empty E.164 standard compliant identifier string", multiFactorInfo.PhoneNumber) } // The PhoneNumber field is deprecated, set it in PhoneMultiFactorInfo and inform about the deprecation. - multiFactorInfo.PhoneMultiFactorInfo = &PhoneMultiFactorInfo{ + multiFactorInfo.Phone = &PhoneMultiFactorInfo{ PhoneNumber: multiFactorInfo.PhoneNumber, } } else { @@ -1121,7 +1121,7 @@ func (r *userQueryResponse) makeExportedUserRecord() (*ExportedUserRecord, error EnrollmentTimestamp: enrollmentTimestamp, FactorID: phoneMultiFactorID, PhoneNumber: factor.PhoneInfo, - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: factor.PhoneInfo, }, }) @@ -1131,7 +1131,7 @@ func (r *userQueryResponse) makeExportedUserRecord() (*ExportedUserRecord, error DisplayName: factor.DisplayName, EnrollmentTimestamp: enrollmentTimestamp, FactorID: totpMultiFactorID, - TOTPMultiFactorInfo: &TOTPMultiFactorInfo{}, + TOTP: &TOTPMultiFactorInfo{}, }) } else { return nil, fmt.Errorf("unsupported multi-factor auth response: %#v", factor) diff --git a/auth/user_mgt_test.go b/auth/user_mgt_test.go index 0f227d69..ffa48655 100644 --- a/auth/user_mgt_test.go +++ b/auth/user_mgt_test.go @@ -72,7 +72,7 @@ var testUser = &UserRecord{ UID: "enrolledPhoneFactor", FactorID: "phone", EnrollmentTimestamp: 1614776780000, - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+1234567890", }, PhoneNumber: "+1234567890", @@ -82,7 +82,7 @@ var testUser = &UserRecord{ UID: "enrolledTOTPFactor", FactorID: "totp", EnrollmentTimestamp: 1614776780000, - TOTPMultiFactorInfo: &TOTPMultiFactorInfo{}, + TOTP: &TOTPMultiFactorInfo{}, DisplayName: "My MFA TOTP", }, }, @@ -657,7 +657,7 @@ func TestInvalidCreateUser(t *testing.T) { EnrolledFactors: []*MultiFactorInfo{ { UID: "EnrollmentID", - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, DisplayName: "Spouse's phone number", @@ -670,7 +670,7 @@ func TestInvalidCreateUser(t *testing.T) { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "invalid", }, DisplayName: "Spouse's phone number", @@ -683,7 +683,7 @@ func TestInvalidCreateUser(t *testing.T) { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, DisplayName: "Spouse's phone number", @@ -697,7 +697,7 @@ func TestInvalidCreateUser(t *testing.T) { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, DisplayName: "Spouse's phone number", @@ -710,7 +710,7 @@ func TestInvalidCreateUser(t *testing.T) { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, FactorID: "phone", @@ -793,7 +793,7 @@ var createUserCases = []struct { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, DisplayName: "Phone Number active", @@ -821,14 +821,14 @@ var createUserCases = []struct { (&UserToCreate{}).MFASettings(MultiFactorSettings{ EnrolledFactors: []*MultiFactorInfo{ { - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, DisplayName: "number1", FactorID: "phone", }, { - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, DisplayName: "number2", @@ -911,7 +911,7 @@ func TestInvalidUpdateUser(t *testing.T) { EnrolledFactors: []*MultiFactorInfo{ { UID: "enrolledSecondFactor1", - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, FactorID: "phone", @@ -924,7 +924,7 @@ func TestInvalidUpdateUser(t *testing.T) { EnrolledFactors: []*MultiFactorInfo{ { UID: "enrolledSecondFactor1", - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "invalid", }, DisplayName: "Spouse's phone number", @@ -1078,7 +1078,7 @@ var updateUserCases = []struct { EnrolledFactors: []*MultiFactorInfo{ { UID: "enrolledSecondFactor1", - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, DisplayName: "Spouse's phone number", @@ -1086,14 +1086,14 @@ var updateUserCases = []struct { EnrollmentTimestamp: time.Now().Unix(), }, { UID: "enrolledSecondFactor2", - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, PhoneNumber: "+11234567890", DisplayName: "Spouse's phone number", FactorID: "phone", }, { - PhoneMultiFactorInfo: &PhoneMultiFactorInfo{ + Phone: &PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, PhoneNumber: "+11234567890", diff --git a/integration/auth/user_mgt_test.go b/integration/auth/user_mgt_test.go index 8b79ab4f..1c37cd0a 100644 --- a/integration/auth/user_mgt_test.go +++ b/integration/auth/user_mgt_test.go @@ -439,7 +439,7 @@ func TestCreateUserMFA(t *testing.T) { FactorID: "phone", }, { - PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + Phone: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+19876543210", }, DisplayName: "Phone Number active", @@ -457,7 +457,7 @@ func TestCreateUserMFA(t *testing.T) { UID: user.MultiFactor.EnrolledFactors[0].UID, DisplayName: "Phone Number deprecated", FactorID: "phone", - PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + Phone: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, PhoneNumber: "+11234567890", @@ -467,7 +467,7 @@ func TestCreateUserMFA(t *testing.T) { UID: user.MultiFactor.EnrolledFactors[1].UID, DisplayName: "Phone Number active", FactorID: "phone", - PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + Phone: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+19876543210", }, PhoneNumber: "+19876543210", @@ -745,7 +745,7 @@ func TestUpdateUserMFA(t *testing.T) { MFASettings(auth.MultiFactorSettings{ EnrolledFactors: []*auth.MultiFactorInfo{ { - PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + Phone: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, DisplayName: "Phone Number active", @@ -773,7 +773,7 @@ func TestUpdateUserMFA(t *testing.T) { { DisplayName: "Phone Number active updated", FactorID: "phone", - PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + Phone: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, }, @@ -809,7 +809,7 @@ func TestUpdateUserMFA(t *testing.T) { EnrolledFactors: []*auth.MultiFactorInfo{ { UID: updatedUser.MultiFactor.EnrolledFactors[0].UID, - PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + Phone: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+11234567890", }, PhoneNumber: "+11234567890", @@ -819,7 +819,7 @@ func TestUpdateUserMFA(t *testing.T) { }, { UID: updatedUser.MultiFactor.EnrolledFactors[1].UID, - PhoneMultiFactorInfo: &auth.PhoneMultiFactorInfo{ + Phone: &auth.PhoneMultiFactorInfo{ PhoneNumber: "+19876543210", }, PhoneNumber: "+19876543210", From 115918b3f0c0fea2b08ba896ce56f8be9a359c36 Mon Sep 17 00:00:00 2001 From: Pragati Date: Tue, 22 Aug 2023 15:15:11 -0700 Subject: [PATCH 08/11] TW feedback changes --- auth/user_mgt.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/auth/user_mgt.go b/auth/user_mgt.go index a25593b5..924a7fb6 100644 --- a/auth/user_mgt.go +++ b/auth/user_mgt.go @@ -70,15 +70,15 @@ type multiFactorInfoResponse struct { EnrolledAt string `json:"enrolledAt,omitempty"` } -// TOTPInfo describes a server side user enrolled second totp factor. +// TOTPInfo describes a user enrolled second TOTP factor. type TOTPInfo struct{} -// PhoneMultiFactorInfo describes a user enrolled second phone factor. +// PhoneMultiFactorInfo describes a user enrolled in SMS second factor. type PhoneMultiFactorInfo struct { PhoneNumber string } -// TOTPMultiFactorInfo describes a user enrolled second totp factor. +// TOTPMultiFactorInfo describes a user enrolled in TOTP second factor. type TOTPMultiFactorInfo struct{} type multiFactorEnrollments struct { From 780bd88dddb380d5c6aea80b57d74f7146fb45d5 Mon Sep 17 00:00:00 2001 From: Pragati Date: Wed, 6 Sep 2023 11:49:00 -0700 Subject: [PATCH 09/11] remove duplicate changes --- auth/user_mgt.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/auth/user_mgt.go b/auth/user_mgt.go index 0efaeb78..924a7fb6 100644 --- a/auth/user_mgt.go +++ b/auth/user_mgt.go @@ -85,10 +85,6 @@ type multiFactorEnrollments struct { Enrollments []*multiFactorInfoResponse `json:"enrollments"` } -type multiFactorEnrollments struct { - Enrollments []*multiFactorInfoResponse `json:"enrollments"` -} - // MultiFactorInfo describes a user enrolled second phone factor. type MultiFactorInfo struct { UID string From 7194d445c162c9abdf9a67d67d28dd35daba5678 Mon Sep 17 00:00:00 2001 From: Pragati Date: Wed, 6 Sep 2023 11:50:32 -0700 Subject: [PATCH 10/11] fix tests failed due to merging --- auth/user_mgt_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/auth/user_mgt_test.go b/auth/user_mgt_test.go index e61ed99d..ffa48655 100644 --- a/auth/user_mgt_test.go +++ b/auth/user_mgt_test.go @@ -1099,10 +1099,6 @@ var updateUserCases = []struct { PhoneNumber: "+11234567890", DisplayName: "Spouse's phone number", FactorID: "phone", - }, { - PhoneNumber: "+11234567890", - DisplayName: "Spouse's phone number", - FactorID: "phone", }, }, }), From 8edadd816dcb56062857f4f43fdd91caa29c4586 Mon Sep 17 00:00:00 2001 From: Pragati Date: Tue, 7 Nov 2023 13:48:40 -0800 Subject: [PATCH 11/11] remove overriding statement --- auth/user_mgt.go | 1 - 1 file changed, 1 deletion(-) diff --git a/auth/user_mgt.go b/auth/user_mgt.go index 924a7fb6..601c1e03 100644 --- a/auth/user_mgt.go +++ b/auth/user_mgt.go @@ -191,7 +191,6 @@ func convertMultiFactorInfoToServerFormat(mfaInfo MultiFactorInfo) (multiFactorI if mfaInfo.UID != "" { authFactorInfo.MFAEnrollmentID = mfaInfo.UID } - authFactorInfo.MFAEnrollmentID = mfaInfo.UID switch mfaInfo.FactorID { case phoneMultiFactorID: