diff --git a/packages/dashboard-api/internal/api/api.gen.go b/packages/dashboard-api/internal/api/api.gen.go index 4e82576a6d..dfb028466a 100644 --- a/packages/dashboard-api/internal/api/api.gen.go +++ b/packages/dashboard-api/internal/api/api.gen.go @@ -164,10 +164,12 @@ type AdminAuthProviderProfilesResponse struct { // AdminAuthProviderUserBootstrapRequest defines model for AdminAuthProviderUserBootstrapRequest. type AdminAuthProviderUserBootstrapRequest struct { - OidcIssuer string `json:"oidc_issuer"` - OidcUserEmail openapi_types.Email `json:"oidc_user_email"` - OidcUserId string `json:"oidc_user_id"` - OidcUserName *string `json:"oidc_user_name,omitempty"` + OidcIssuer string `json:"oidc_issuer"` + OidcUserEmail openapi_types.Email `json:"oidc_user_email"` + OidcUserId string `json:"oidc_user_id"` + OidcUserName *string `json:"oidc_user_name,omitempty"` + SignupIp *string `json:"signup_ip,omitempty"` + SignupUserAgent *string `json:"signup_user_agent,omitempty"` } // AdminTeamBootstrapRequest defines model for AdminTeamBootstrapRequest. @@ -1317,74 +1319,74 @@ func RegisterHandlersWithOptions(router gin.IRouter, si ServerInterface, options // times slower for the Go compiler than parsing a slice literal. var swaggerSpec = []string{ "7F3rbtw6kn4VQrvAzgCy23GSxa6B+eGOk3OMTXYDOxksEAQOW6ru5kQidUjKcY9Pv/uAN4lqUTfbbdhB", - "fiWWSNaFH4vFqqL6NkpYXjAKVIro5DYqMMc5SOD6r0VJsvSKpOr/KYiEk0ISRqOT6DwFKsmSAEdsieQa", - "kG57GMURUe8LLNdRHFGcQ3RSjxNHHP4oCYc0OpG8hDgSyRpyrAgsGc+xjE6istQt5aZQfYXkhK6i7Tau", - "hrli/EpCXmRYQpu1/9P/wRlakkwCR4uN4Q2RiucYue6Nh4zXz3FGsKjE+aMEvmnL02DEl6Wbd9Fm+A3L", - "c3wgQOleQooyIqTSquH6/EwgydAKJBISy1KAQEvGFWtwU2QshehkiTMB/ayKXt0TCbkYMQlxlOObc9P4", - "xdFR9R5zjhXRkpI/SrANFJFtHAm5yVQbNXRUacLJMlUdlQ4kQ4QmWZnCWFVUJIOS/zuHZXQS/dusXhAz", - "00zM5or0pe6uJGgI3SWhuEpKLhgPCKifIw6y5BRSBVC1gAoO14SVwgjMQRSMCkCEom8JB6WKKyz/dPP5", - "DZmp6oKoJT4ClOIqIzmRbT4/4BuSlzmiZb4w61wrS2ne8I4K4KjAK+hiwgzs85DCEpeZjE5eH8U12AiV", - "L48jDS5F0WIrJ9T+VamcUAkr4Jp5gWm6YDfnZ2Osk23cYZ/qofoWSVt/EnA+jr5q2UHcDnI/06gGuczK", - "VZuXT4BzJLJyZeZNsOy6c75Us8kqMOZPXCVFeZWwkgaQ9M5Y4qqtgjzc4ESi6zcfPyPdqxPIRflGjxpU", - "SIWcfqx4XD7YorwVjMvtn7fXOCth++eto3F+tq0WJ7qAf0CirBhRq0cg1QelDASiTKIcy2St6SiVg7jf", - "aq6FfJ4LuuY/h5zxzVW+mAIl0wkJ8k89Px/mXUKYhh/mD4SoolxkJBnH6TURZEEyIjfoL2ptob8h0z1G", - "euNCf0OKCKc4+2sX+5ZeAAsLxjLAdIc/AZgn6wDisYADQgVQQSS5BiTKhUGTxSWjtTukaIvYeEX6PzT1", - "fahOg2Joj8WtWh1tRi/VmklYVuZU000Jh0S966SqhgmCNKp30itFRHkOVE3yF933CutH+r/2dWXV7Lv6", - "b9ugwqptUP/tRqhJ4t0HtklZpM0m3gPd5GvI5pcC+Pko31y17Nh97CD32X22qrMxjNqTenV0pP5JGJVg", - "dgNcFBlJsOJv9g+hmLz1xu/zvN5yzrih0RRyjlNnNJXL9eroxf5pnpZyrVRrRkVg2iniL/dP/B3jC5Km", - "QA3FV/un+L9MoiUraaoovn6MSb0Efg28Vuzro+P9E/1cCMmVk2TJbh32NZhP01R5UB9AbZkXFnDqoMxZ", - "AVwSA3nIMckaa8U8CS3beqF9sa3q1c0Wyl1Qop+mOaEKcB85uyYp8I+cLUkGPbSbYr1VjxFOUw5CoCVn", - "uTYFCaNLsio5pAiXco0KO7wyD7TMMrxQNIwJaB3+Oi2O3bPQ2+O5NjbesVoNPOy/+kqpTNJ07Yj3jH0v", - "Cy37E5gscWH87U5WjKjiXkfwnFD354jzeFDXYrJU2tq35Slsi9En606Yt47ZO4xXlEZx/lkAnzMmheS4", - "6JwNRtLkighRgj4g5IS+B7qSa1+z9TTo1kp/V6MB5XcyUbXRNMx2fTu0Rne05Eu0Q7wtQKcmlQEc1l6H", - "HZqTLCN0NVNGXLnpupk6HzXOxcOacwoInG7Vq0Pjsncrc0czerg+E6NjPud0ydqSWgfuNOCr6l5IN1Au", - "giQ5CInzQp1ILt69efny5X97gZtKauXtHajGIcmXhBKx7qXH8iKDIYqxOoS6wTrJD24C+igQmgn/qIA4", - "ZDp6JxmSayJM9E5zgK8x0RS0R+qMRJtMmA8v6KbDcdMid6bTBxACrwJoeodJVnJAuWmAfqyB2ogjIgJ9", - "W2KSQfotRkyugf8gAtA3xee3EbvnDv5qDDUmuJJrl9dOiF5WegghwzKf46KAVK+6FIv1gmGeoiQjSleH", - "3iFIz5JiN46MrIqPMklAiMAZpMGB2mTaS+WJYXdiKmNwK37mINRCVYALwHAQfeI9EbLbH0ixHB9lV0NB", - "qocNRdkp3Mg3/dE7yVCBhTBGB5Dq4QJ3etPSKR6jLIUnpT9QOqXMtHWhr2la1EI2+OtW16XNQXSrbFGD", - "JWRm3wezIb4lHYlEvV6HvKwmMyGx3nz8/CYc9DWRXW7SVX4QPmoGCv/z1UC0LY7eaGOp9vpO78O5Bzm+", - "cT7A8evXd/AJQkKemfjRJy/n2KRu42Kjob4z4KnqHsK81n+l31aMsq0p3cEc0QaNV8ONGeeKAL1O/w5c", - "EHPyHmlvW4/rkOlu5DKOOM4/LHal1RhpSysK/IMG1dPRQTKJszMivl+Sf0IHmQ6hvFGuk6IcRTBkbh1U", - "6rlyMtuB21zGDW+hiv964GioYgSCDeDCMA57Y8qpK3ByhzOIGXQEUz1GsQoR33WFDVq6mkKQUzcZ87ad", - "U+9M1mHHzuksBJn3mrujEL5MqKp97NAJ7lacRzVG6t1hFI8xEXmX42FGsq8PB8Mhmp16uJDafgecyXX3", - "tHay8nuZY3rAAacKZ2itx0HJGpLviIMoMznMXx9jvqvx63j3y0VucNxdWvSpUR1kyBYcBFDp06oSY+dn", - "h1EPgXHJG9d6GPFmAup6JI9O57ky7jqJhpbNB5c5baeWTfL1DhbwxfF/hazUpRnhAhLG056daidDo+dl", - "R3FB38dVFQzgsnJvt3GUNjaB3s2nbqn6sRwTGljcWAAyLxWUODRUJzleLkmi8Iz1AZwozI6Ab+5NUh+T", - "1WTesZamY7HzDtP5ieR2ofpS/sAC2U6jDaaQrCimE9Gd7mwW6+qOKWvW5F1+rEmyVhPpM2WX3eCi9gjH", - "jUKlWtexXyTjVTd4gA2t5jqvFVhfaQrpfBM6RwyqavhcMThEFUvu2J4Gdx0izlzOP3TIGBlNj12a4SNJ", - "ZMnhM2+G+UtOxkjjcmxN77UNsT7/lNQJMV+6naNBRah/vkWfS6YbjPazPRANieCG7uKtSpZ18TZy7oWt", - "gxsT+1JNu/iZdtwfmM47n+XPxp3lvf1sxDn4Dkd/28XYhF3Id2SCRjqb09LDJA3OmK3xOfMt8wgOmpv6", - "HYIBk0Mi/ZYpw0JeqrP8/Qyo7wSMwEOV0xkP574YzvS4TGN3bdcdmHKo8XDt20Pdshqxa3rBljpsY3TV", - "NLw1g/5C2Z3NhmJ24jc+jHyQDBkn8UDB94bB+/mi75/1BO1EkHNCP3oaexE/REy5w2cYFqqX53tuiU6S", - "h+K1tZF2hs4/C+BKhECiI2PJd0gvAIuRpvMuAev7O5JzTCmkYUNHxNxI0fW639aTnMjBlek0+N60fujZ", - "7PSX4kgSczQYO/+xu0CgO9buapstX3OejuMdUDQ9XasuHwd9iHtfaXc3jEqTknOg0sYYQIx0yOqezlKa", - "pN7I7mpjaeccuqK0zub8zkouRm6jOb65CKVPumn8PZDKCLbe9eWb7MVBrfZorCbucV2pqG9ae7MEOB9/", - "cqks03BqQA3b5kktHUhKTuTmUo0JtmA0J/S0IP8Dm9NS6rp7XXa9BpzqVWELr///QLc8+MS+A60VjnVP", - "XXrl1a/NAXPgbryF/uudmzITHrqSdiAtn7Y0ulk99FrKYndgpYABNlWTA+0vtVi8LAu8wAJeaCEGxnGN", - "uyV2LY5HcFWPpqawNZiaHGKLtySR+nre2+M5OquqX04/nkdxdO089+jo8MXhka65K4DigkQn0cvDo8Mj", - "Zb+wXOu5nWE1ZTMNiNnCVcRpIDIRSoFrQyX0rQV9Nle0BMK67E0HSzFFeswDXNeWQ4qqsdEPxr8vM/ZD", - "OUYK6zrxcJ5GJ9FHJmRVnieq+jxbyg9Czlm6ebDy6e5CwG1zvdhbn40bAccPWDweihSESslN1dKyzLJN", - "rc4CUltyqIvoj7qIVdzPVKP6fsFQ2xdeqXx/29dmXFvhPtT2uGFtopMvATvz5ev2axyJMs8x30QnUTVR", - "WmK1RPBK6ISs6hl9VSNaQJcC+IGrqJ0tNgeV2+Rw3QE9ZUNdVfB889bu93vD38iK70dG5HCd9BA+9S0L", - "c+uK0BVyM/FEUDoZeWZKzEUAJ4u+p+dqe0cC0d5WnYhDaxweG4c7pf7PDoNW2emzR5+diCb8JqDu1tyJ", - "2Cr+VhBA3W/QBt1nd2fF/4DGl7CAdZOZveqiBHjy5skq6LnC4jeQDUgMIqLDw+uxQI/jhA3ea3luDpm5", - "nfo8UVU7WY3bdFomD2H2CNlCmLM106FmDI4PuKdneR4SGU9stnvmd1HFhLp2jyoGMm3Kgl8d2sYj+1Wl", - "4mN7uM9IjG9vv1KxV0wFbh0Mezb2mx4FXhFqztd6lL0aHXspfKjty/tBNhSB+fI1GEr58lXNZFdUSXUK", - "B4Za3j0R0gQwFg7HbhnYB/46mPkfeupfEJf1ZYa7LQzxGNBr3eAYDb+dKxu/sDcde8qJa9186UPfrcPG", - "dhh/86oe/27wewT06fuoEwGXgsQkE4f7BJH9HsVQ21fPGHBWjV14MyXqfSAzxfDRHiGyU24fwMnvfiG9", - "qEBjVF0J7bfSr2bC5XRmt1UJ4nbGq+LcLpmrXNCl62ULeqeusbrwca+LrFl1PHqhuZrOX0vtnkvNKZI7", - "lLi1VgHQLrcq1WeR15ylCz0xAuEs056Kqbxtplh0LGABGaMrgSSL0Q8i18jkmM1npkziGS0zvGpnX34D", - "qfMu+1zP7ZTnaERq6bToj3h+CoOmHx0B37LmPXDCintOx/WEPHzopX0F9RmEWWyhxFNKeT08ZszM7Ca5", - "/BO5ydd62YQOo6HfV+lZ981M95mS/xD2q0ZyE6NrnJEUS0JX1QfW9E0NZIqcu+1FnZ2YtgFWH/h8chGb", - "KnHgoezn2/qmINJlIDSMHGZ6sXlrPgK7NZ/gluZzjTsGTj3WEPrkPhg7HUGV//TwBrJdYfnIBjJQLjkE", - "XVu2u3/7+NMeyI3Sh42vA/jMu1/SdWjwQG6vq9wP63u0lbvXaUb7Z9o0WF0c/kJTK7SYVxM/2QF8QOTs", - "I4MX+JzkKEP5IvBhXB9a+saer7wnY9B+2hPradpQ+CQD2CgzSCEDc8+siekz/byN6jtWGzhsx/fIDr4a", - "gCGHnF0/USA+K3BdaEWOwpf3bZT+cIiXAXO/quGdbuovlf/Fj3/UjwnNCIUYlTQDIaqu6uDDKMIohdQG", - "V5KsFBL4X21UxfwSC6GrGJkvgpsPiNtvegvG9UHqmmD0HTYCJDKZRMeu/dR3wFFwkk9fCe1fLRixLEJf", - "qJ/UzV4nm9THfkN9Wh/GJwo0Otfb+imFvTtZ7atud8j4Vmz/skb388ykt+hqc1R9PKlpkmbWiAzbJmVM", - "nE1qWx5tReQaCEf6gUvKELpk2pTY65n9ZuLMMbNHwHZ+02o0ZlvSP78IbkuELqxsq+e3jR+sMlUqzV/n", - "gcZDswM2Hrhxt1+3/woAAP//", + "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", } // decodeSpec returns the embedded OpenAPI spec as raw JSON bytes, diff --git a/packages/dashboard-api/internal/handlers/admin_users_bootstrap.go b/packages/dashboard-api/internal/handlers/admin_users_bootstrap.go index d18b872c5f..a9353ea984 100644 --- a/packages/dashboard-api/internal/handlers/admin_users_bootstrap.go +++ b/packages/dashboard-api/internal/handlers/admin_users_bootstrap.go @@ -58,10 +58,12 @@ func (s *APIStore) PostAdminUsersBootstrap(c *gin.Context) { } team, err := s.bootstrapOIDCUser(ctx, oidcUserBootstrapInput{ - OIDCIssuer: oidcIssuer, - OIDCUserID: oidcUserID, - OIDCUserEmail: oidcUserEmail, - OIDCUserName: body.OidcUserName, + OIDCIssuer: oidcIssuer, + OIDCUserID: oidcUserID, + OIDCUserEmail: oidcUserEmail, + OIDCUserName: body.OidcUserName, + SignupIP: strings.TrimSpace(valueOrEmpty(body.SignupIp)), + SignupUserAgent: strings.TrimSpace(valueOrEmpty(body.SignupUserAgent)), }) if err != nil { s.handleProvisioningError(ctx, c, "bootstrap auth provider user", err) @@ -74,3 +76,11 @@ func (s *APIStore) PostAdminUsersBootstrap(c *gin.Context) { Slug: team.Slug, }) } + +func valueOrEmpty(value *string) string { + if value == nil { + return "" + } + + return *value +} diff --git a/packages/dashboard-api/internal/handlers/team_handlers_test.go b/packages/dashboard-api/internal/handlers/team_handlers_test.go index 2fa7a66f42..b4d64e9c9d 100644 --- a/packages/dashboard-api/internal/handlers/team_handlers_test.go +++ b/packages/dashboard-api/internal/handlers/team_handlers_test.go @@ -572,10 +572,12 @@ func TestBootstrapAuthProviderUser_CreatesIdentityAndDefaultTeam(t *testing.T) { } input := oidcUserBootstrapInput{ - OIDCIssuer: "https://ory.example.test", - OIDCUserID: uuid.NewString(), - OIDCUserEmail: "ada@example.test", - OIDCUserName: nil, + OIDCIssuer: "https://ory.example.test", + OIDCUserID: uuid.NewString(), + OIDCUserEmail: "ada@example.test", + OIDCUserName: nil, + SignupIP: "198.51.100.20", + SignupUserAgent: "Mozilla/5.0", } team, err := store.bootstrapOIDCUser(ctx, input) @@ -611,6 +613,18 @@ func TestBootstrapAuthProviderUser_CreatesIdentityAndDefaultTeam(t *testing.T) { if sink.requests[0].CreatorUserID != userIdentity.UserID { t.Fatalf("expected sink creator %s, got %s", userIdentity.UserID, sink.requests[0].CreatorUserID) } + if sink.requests[0].CreatorContext == nil { + t.Fatal("expected sink creator context") + } + if sink.requests[0].CreatorContext.IPAddress != "198.51.100.20" { + t.Fatalf("expected sink creator ip %q, got %q", "198.51.100.20", sink.requests[0].CreatorContext.IPAddress) + } + if sink.requests[0].CreatorContext.UserAgent != "Mozilla/5.0" { + t.Fatalf("expected sink creator user agent %q, got %q", "Mozilla/5.0", sink.requests[0].CreatorContext.UserAgent) + } + if sink.requests[0].CreatorContext.AuthMethod != teamprovision.AuthMethodSocial { + t.Fatalf("expected sink creator auth method %q, got %q", teamprovision.AuthMethodSocial, sink.requests[0].CreatorContext.AuthMethod) + } } func TestBootstrapOIDCUser_ConcurrentRequestsSingleIdentityAndTeam(t *testing.T) { diff --git a/packages/dashboard-api/internal/handlers/utils_team_provisioning.go b/packages/dashboard-api/internal/handlers/utils_team_provisioning.go index 25368fe4e9..0f1dae951c 100644 --- a/packages/dashboard-api/internal/handlers/utils_team_provisioning.go +++ b/packages/dashboard-api/internal/handlers/utils_team_provisioning.go @@ -46,6 +46,7 @@ type bootstrapUserProfile struct { UserID uuid.UUID Email string DefaultTeamName string + CreatorContext *teamprovision.CreatorContextV1 } type bootstrapUserIdentity struct { @@ -54,10 +55,12 @@ type bootstrapUserIdentity struct { } type oidcUserBootstrapInput struct { - OIDCIssuer string - OIDCUserID string - OIDCUserEmail string - OIDCUserName *string + OIDCIssuer string + OIDCUserID string + OIDCUserEmail string + OIDCUserName *string + SignupIP string + SignupUserAgent string } func (s *APIStore) bootstrapSupabaseUser(ctx context.Context, userID uuid.UUID) (provisionedTeam, error) { @@ -111,6 +114,7 @@ func (s *APIStore) bootstrapOIDCUser(ctx context.Context, input oidcUserBootstra UserID: uuid.New(), Email: input.OIDCUserEmail, DefaultTeamName: defaultTeamNameFromOIDCUserName(input.OIDCUserName), + CreatorContext: creatorContextFromSignupMetadata(input.SignupIP, input.SignupUserAgent, teamprovision.AuthMethodSocial), } return s.bootstrapUserWithIdentity(ctx, profile, &bootstrapUserIdentity{ @@ -219,7 +223,7 @@ func (s *APIStore) bootstrapUserWithIdentity(ctx context.Context, profile bootst TeamName: existingTeam.Name, TeamEmail: existingTeam.Email, CreatorUserID: profile.UserID, - CreatorContext: s.resolveTeamCreatorContext(ctx, profile.UserID), + CreatorContext: s.teamCreatorContextForProvisioning(ctx, profile), Reason: teamprovision.ReasonDefaultSignupTeam, } _ = s.teamProvisionSink.ProvisionTeam(ctx, req) @@ -267,7 +271,7 @@ func (s *APIStore) bootstrapUserWithIdentity(ctx context.Context, profile bootst TeamName: team.Name, TeamEmail: team.Email, CreatorUserID: profile.UserID, - CreatorContext: s.resolveTeamCreatorContext(ctx, profile.UserID), + CreatorContext: s.teamCreatorContextForProvisioning(ctx, profile), Reason: teamprovision.ReasonDefaultSignupTeam, } _ = s.teamProvisionSink.ProvisionTeam(ctx, req) @@ -462,7 +466,40 @@ func (s *APIStore) resolveTeamCreatorContext(ctx context.Context, userID uuid.UU return nil } - return creatorContext + return normalizeCreatorContext(creatorContext) +} + +func (s *APIStore) teamCreatorContextForProvisioning(ctx context.Context, profile bootstrapUserProfile) *teamprovision.CreatorContextV1 { + if profile.CreatorContext != nil { + return normalizeCreatorContext(profile.CreatorContext) + } + + return s.resolveTeamCreatorContext(ctx, profile.UserID) +} + +func creatorContextFromSignupMetadata(signupIP, signupUserAgent, authMethod string) *teamprovision.CreatorContextV1 { + return normalizeCreatorContext(&teamprovision.CreatorContextV1{ + IPAddress: signupIP, + UserAgent: signupUserAgent, + AuthMethod: authMethod, + }) +} + +func normalizeCreatorContext(creatorContext *teamprovision.CreatorContextV1) *teamprovision.CreatorContextV1 { + if creatorContext == nil { + return nil + } + + ipAddress := strings.TrimSpace(creatorContext.IPAddress) + if ipAddress == "" { + return nil + } + + return &teamprovision.CreatorContextV1{ + IPAddress: ipAddress, + UserAgent: strings.TrimSpace(creatorContext.UserAgent), + AuthMethod: strings.TrimSpace(creatorContext.AuthMethod), + } } func defaultTeamNameFromProfile(profile userprofile.Profile) string { diff --git a/packages/dashboard-api/internal/userprofile/creator_context.go b/packages/dashboard-api/internal/userprofile/creator_context.go index ecbdc7215f..79f2072ace 100644 --- a/packages/dashboard-api/internal/userprofile/creator_context.go +++ b/packages/dashboard-api/internal/userprofile/creator_context.go @@ -4,30 +4,19 @@ import ( "strings" sharedteamprovision "github.com/e2b-dev/infra/packages/shared/pkg/teamprovision" - "github.com/e2b-dev/infra/packages/shared/pkg/utils" ) const ( signupIPMetadataKey = "signup_ip" signupUserAgentMetadataKey = "signup_user_agent" - ipMetadataKey = "ip" - ipAddressMetadataKey = "ip_address" - userAgentMetadataKey = "user_agent" providersMetadataKey = "providers" providerMetadataKey = "provider" ) func creatorContextFromMetadata(metadata map[string]any, providerNames []string) *sharedteamprovision.CreatorContextV1 { return &sharedteamprovision.CreatorContextV1{ - IPAddress: utils.FirstNonEmpty( - metadataString(metadata, signupIPMetadataKey), - metadataString(metadata, ipAddressMetadataKey), - metadataString(metadata, ipMetadataKey), - ), - UserAgent: utils.FirstNonEmpty( - metadataString(metadata, signupUserAgentMetadataKey), - metadataString(metadata, userAgentMetadataKey), - ), + IPAddress: metadataString(metadata, signupIPMetadataKey), + UserAgent: metadataString(metadata, signupUserAgentMetadataKey), AuthMethod: authMethodFromProviderNames(providerNames), } } diff --git a/packages/dashboard-api/internal/userprofile/ory_test.go b/packages/dashboard-api/internal/userprofile/ory_test.go index fa45eada80..7e6c807fb2 100644 --- a/packages/dashboard-api/internal/userprofile/ory_test.go +++ b/packages/dashboard-api/internal/userprofile/ory_test.go @@ -145,8 +145,10 @@ func TestCreatorContextFromOryIdentityUsesMetadataAdmin(t *testing.T) { identity := ory.Identity{ Id: uuid.NewString(), MetadataAdmin: map[string]any{ - "ip_address": "198.51.100.20", - "user_agent": "Dashboard/1.0", + "signup_ip": "198.51.100.20", + "signup_user_agent": "Dashboard/1.0", + "ip_address": "should-not-be-used", + "user_agent": "should-not-be-used", }, MetadataPublic: map[string]any{ "signup_ip": "should-not-be-used", diff --git a/packages/dashboard-api/internal/userprofile/supabase.go b/packages/dashboard-api/internal/userprofile/supabase.go index 1f1d1194c7..fb6805f5e1 100644 --- a/packages/dashboard-api/internal/userprofile/supabase.go +++ b/packages/dashboard-api/internal/userprofile/supabase.go @@ -7,12 +7,10 @@ import ( "strings" "github.com/google/uuid" - "go.uber.org/zap" "github.com/e2b-dev/infra/packages/db/pkg/dberrors" supabasedb "github.com/e2b-dev/infra/packages/db/pkg/supabase" supabasequeries "github.com/e2b-dev/infra/packages/db/pkg/supabase/queries" - "github.com/e2b-dev/infra/packages/shared/pkg/logger" sharedteamprovision "github.com/e2b-dev/infra/packages/shared/pkg/teamprovision" "github.com/e2b-dev/infra/packages/shared/pkg/utils" ) @@ -82,28 +80,8 @@ func (p *supabaseProvider) GetTeamCreatorContext(ctx context.Context, userID uui } appMetadata := rawUserMetadata(authUser.RawAppMetaData) - creatorContext := creatorContextFromMetadata(appMetadata, providerNamesFromSupabaseMetadata(appMetadata)) - - if creatorContext.AuthMethod == sharedteamprovision.AuthMethodSocial && (creatorContext.IPAddress == "" || creatorContext.UserAgent == "") { - session, sessionErr := p.queries.GetLatestAuthSessionByUserID(ctx, userID) - if sessionErr != nil { - if !dberrors.IsNotFoundError(sessionErr) { - logger.L().Warn(ctx, "failed to resolve latest auth session for creator context, falling back to metadata", - zap.String("user_id", userID.String()), - zap.Error(sessionErr), - ) - } - } else { - if creatorContext.IPAddress == "" { - creatorContext.IPAddress = utils.DerefOrDefault(session.Ip, "") - } - if creatorContext.UserAgent == "" { - creatorContext.UserAgent = utils.DerefOrDefault(session.UserAgent, "") - } - } - } - return creatorContext, nil + return creatorContextFromMetadata(appMetadata, providerNamesFromSupabaseMetadata(appMetadata)), nil } func profileFromAuthUser(user supabasequeries.AuthUser) Profile { diff --git a/packages/dashboard-api/internal/userprofile/supabase_test.go b/packages/dashboard-api/internal/userprofile/supabase_test.go index ea5b34c319..9952d51002 100644 --- a/packages/dashboard-api/internal/userprofile/supabase_test.go +++ b/packages/dashboard-api/internal/userprofile/supabase_test.go @@ -81,6 +81,8 @@ func TestSupabaseCreatorContextFromMetadata(t *testing.T) { metadata := map[string]any{ "signup_ip": "203.0.113.10", "signup_user_agent": "Mozilla/5.0", + "ip_address": "should-not-be-used", + "user_agent": "should-not-be-used", "providers": []any{"email", "github"}, } @@ -95,3 +97,25 @@ func TestSupabaseCreatorContextFromMetadata(t *testing.T) { t.Fatalf("AuthMethod = %q, want %q", got.AuthMethod, sharedteamprovision.AuthMethodSocial) } } + +func TestCreatorContextFromMetadataIgnoresNonSignupNetworkFields(t *testing.T) { + t.Parallel() + + metadata := map[string]any{ + "ip": "203.0.113.99", + "ip_address": "203.0.113.98", + "user_agent": "should-not-be-used", + "providers": []any{"email"}, + } + + got := creatorContextFromMetadata(metadata, providerNamesFromSupabaseMetadata(metadata)) + if got.IPAddress != "" { + t.Fatalf("IPAddress = %q, want empty", got.IPAddress) + } + if got.UserAgent != "" { + t.Fatalf("UserAgent = %q, want empty", got.UserAgent) + } + if got.AuthMethod != sharedteamprovision.AuthMethodPassword { + t.Fatalf("AuthMethod = %q, want %q", got.AuthMethod, sharedteamprovision.AuthMethodPassword) + } +} diff --git a/spec/openapi-dashboard.yml b/spec/openapi-dashboard.yml index 8e21049a31..94594e0bb4 100644 --- a/spec/openapi-dashboard.yml +++ b/spec/openapi-dashboard.yml @@ -313,6 +313,10 @@ components: oidc_user_name: type: string nullable: true + signup_ip: + type: string + signup_user_agent: + type: string AdminTeamBootstrapRequest: type: object