mirror of
https://github.com/pocketbase/pocketbase.git
synced 2025-03-21 06:36:27 +02:00
prioritized user submitted OAuth2 createData.email
This commit is contained in:
parent
acd72101c6
commit
9856c59de0
@ -1,3 +1,8 @@
|
|||||||
|
## v0.26.0 (WIP)
|
||||||
|
|
||||||
|
- ⚠️ Prioritized the user submitted non-empty `createData.email` (_it will be unverified_) when creating the PocketBase user during the first OAuth2 auth.
|
||||||
|
|
||||||
|
|
||||||
## v0.25.0
|
## v0.25.0
|
||||||
|
|
||||||
- ⚠️ Upgraded Google OAuth2 auth, token and userinfo endpoints to their latest versions.
|
- ⚠️ Upgraded Google OAuth2 auth, token and userinfo endpoints to their latest versions.
|
||||||
|
@ -232,7 +232,11 @@ func oauth2Submit(e *core.RecordAuthWithOAuth2RequestEvent, optExternalAuth *cor
|
|||||||
payload = map[string]any{}
|
payload = map[string]any{}
|
||||||
}
|
}
|
||||||
|
|
||||||
payload[core.FieldNameEmail] = e.OAuth2User.Email
|
// assign the OAuth2 user email only if the user hasn't submitted one
|
||||||
|
// (ignore empty/invalid values for consistency with the OAuth2->existing user update flow)
|
||||||
|
if v, _ := payload[core.FieldNameEmail].(string); v == "" {
|
||||||
|
payload[core.FieldNameEmail] = e.OAuth2User.Email
|
||||||
|
}
|
||||||
|
|
||||||
// map known fields (unless the field was explicitly submitted as part of CreateData)
|
// map known fields (unless the field was explicitly submitted as part of CreateData)
|
||||||
if _, ok := payload[e.Collection.OAuth2.MappedFields.Id]; !ok && e.Collection.OAuth2.MappedFields.Id != "" {
|
if _, ok := payload[e.Collection.OAuth2.MappedFields.Id]; !ok && e.Collection.OAuth2.MappedFields.Id != "" {
|
||||||
|
@ -877,7 +877,7 @@ func TestRecordAuthWithOAuth2(t *testing.T) {
|
|||||||
`"verified":{"code":"validation_values_mismatch"`,
|
`"verified":{"code":"validation_values_mismatch"`,
|
||||||
},
|
},
|
||||||
NotExpectedContent: []string{
|
NotExpectedContent: []string{
|
||||||
`"email":`, // the value is always overwritten with the OAuth2 user email
|
`"email":`, // ignored because the record validator never ran
|
||||||
`"rel":`, // ignored because the record validator never ran
|
`"rel":`, // ignored because the record validator never ran
|
||||||
`"file":`, // ignored because the record validator never ran
|
`"file":`, // ignored because the record validator never ran
|
||||||
},
|
},
|
||||||
@ -930,12 +930,10 @@ func TestRecordAuthWithOAuth2(t *testing.T) {
|
|||||||
ExpectedStatus: 400,
|
ExpectedStatus: 400,
|
||||||
ExpectedContent: []string{
|
ExpectedContent: []string{
|
||||||
`"data":{`,
|
`"data":{`,
|
||||||
|
`"email":{"code":"validation_is_email"`,
|
||||||
`"rel":{"code":"validation_missing_rel_records"`,
|
`"rel":{"code":"validation_missing_rel_records"`,
|
||||||
`"file":{"code":"validation_invalid_file"`,
|
`"file":{"code":"validation_invalid_file"`,
|
||||||
},
|
},
|
||||||
NotExpectedContent: []string{
|
|
||||||
`"email":`, // the value is always overwritten with the OAuth2 user email
|
|
||||||
},
|
|
||||||
ExpectedEvents: map[string]int{
|
ExpectedEvents: map[string]int{
|
||||||
"*": 0,
|
"*": 0,
|
||||||
"OnRecordAuthWithOAuth2Request": 1,
|
"OnRecordAuthWithOAuth2Request": 1,
|
||||||
@ -949,7 +947,7 @@ func TestRecordAuthWithOAuth2(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "creating user (valid create data)",
|
Name: "creating user (valid create data with empty submitted email)",
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
URL: "/api/collections/users/auth-with-oauth2",
|
URL: "/api/collections/users/auth-with-oauth2",
|
||||||
Body: strings.NewReader(`{
|
Body: strings.NewReader(`{
|
||||||
@ -957,7 +955,7 @@ func TestRecordAuthWithOAuth2(t *testing.T) {
|
|||||||
"code":"123",
|
"code":"123",
|
||||||
"redirectURL": "https://example.com",
|
"redirectURL": "https://example.com",
|
||||||
"createData": {
|
"createData": {
|
||||||
"email": "invalid",
|
"email": "",
|
||||||
"emailVisibility": true,
|
"emailVisibility": true,
|
||||||
"password": "1234567890",
|
"password": "1234567890",
|
||||||
"passwordConfirm": "1234567890",
|
"passwordConfirm": "1234567890",
|
||||||
@ -1041,6 +1039,95 @@ func TestRecordAuthWithOAuth2(t *testing.T) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "creating user (valid create data with non-empty valid submitted email)",
|
||||||
|
Method: http.MethodPost,
|
||||||
|
URL: "/api/collections/users/auth-with-oauth2",
|
||||||
|
Body: strings.NewReader(`{
|
||||||
|
"provider": "test",
|
||||||
|
"code":"123",
|
||||||
|
"redirectURL": "https://example.com",
|
||||||
|
"createData": {
|
||||||
|
"email": "test_create@example.com",
|
||||||
|
"emailVisibility": true,
|
||||||
|
"password": "1234567890",
|
||||||
|
"passwordConfirm": "1234567890",
|
||||||
|
"name": "test_name",
|
||||||
|
"username": "test_username",
|
||||||
|
"rel": "0yxhwia2amd8gec"
|
||||||
|
}
|
||||||
|
}`),
|
||||||
|
BeforeTestFunc: func(t testing.TB, app *tests.TestApp, e *core.ServeEvent) {
|
||||||
|
usersCol, err := app.FindCollectionByNameOrId("users")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// register the test provider
|
||||||
|
auth.Providers["test"] = func() auth.Provider {
|
||||||
|
return &oauth2MockProvider{
|
||||||
|
AuthUser: &auth.AuthUser{
|
||||||
|
Id: "test_id",
|
||||||
|
Email: "oauth2@example.com", // should be ignored because of the explicit submitted email
|
||||||
|
},
|
||||||
|
Token: &oauth2.Token{AccessToken: "abc"},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the test provider in the collection
|
||||||
|
usersCol.MFA.Enabled = false
|
||||||
|
usersCol.OAuth2.Enabled = true
|
||||||
|
usersCol.OAuth2.Providers = []core.OAuth2ProviderConfig{{
|
||||||
|
Name: "test",
|
||||||
|
ClientId: "123",
|
||||||
|
ClientSecret: "456",
|
||||||
|
}}
|
||||||
|
if err := app.Save(usersCol); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ExpectedStatus: 200,
|
||||||
|
ExpectedContent: []string{
|
||||||
|
`"email":"test_create@example.com"`,
|
||||||
|
`"emailVisibility":true`,
|
||||||
|
`"name":"test_name"`,
|
||||||
|
`"username":"test_username"`,
|
||||||
|
`"verified":false`,
|
||||||
|
`"rel":"0yxhwia2amd8gec"`,
|
||||||
|
},
|
||||||
|
NotExpectedContent: []string{
|
||||||
|
// hidden fields
|
||||||
|
`"tokenKey"`,
|
||||||
|
`"password"`,
|
||||||
|
},
|
||||||
|
ExpectedEvents: map[string]int{
|
||||||
|
"*": 0,
|
||||||
|
"OnRecordAuthWithOAuth2Request": 1,
|
||||||
|
"OnRecordAuthRequest": 1,
|
||||||
|
"OnRecordCreateRequest": 1,
|
||||||
|
"OnRecordEnrich": 2, // the auth response and from the create request
|
||||||
|
// ---
|
||||||
|
"OnModelCreate": 3, // record + authOrigins + externalAuths
|
||||||
|
"OnModelCreateExecute": 3,
|
||||||
|
"OnModelAfterCreateSuccess": 3,
|
||||||
|
"OnRecordCreate": 3,
|
||||||
|
"OnRecordCreateExecute": 3,
|
||||||
|
"OnRecordAfterCreateSuccess": 3,
|
||||||
|
// ---
|
||||||
|
"OnModelValidate": 3,
|
||||||
|
"OnRecordValidate": 3,
|
||||||
|
},
|
||||||
|
AfterTestFunc: func(t testing.TB, app *tests.TestApp, res *http.Response) {
|
||||||
|
user, err := app.FindFirstRecordByData("users", "username", "test_username")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !user.ValidatePassword("1234567890") {
|
||||||
|
t.Fatalf("Expected password %q to be valid", "1234567890")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "creating user (with mapped OAuth2 fields and avatarURL->file field)",
|
Name: "creating user (with mapped OAuth2 fields and avatarURL->file field)",
|
||||||
Method: http.MethodPost,
|
Method: http.MethodPost,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user