diff --git a/backend/internal/dto/oidc_dto.go b/backend/internal/dto/oidc_dto.go index da26686a..08e271bb 100644 --- a/backend/internal/dto/oidc_dto.go +++ b/backend/internal/dto/oidc_dto.go @@ -139,6 +139,7 @@ type OidcDeviceAuthorizationRequestDto struct { ClientSecret string `form:"client_secret"` ClientAssertion string `form:"client_assertion"` ClientAssertionType string `form:"client_assertion_type"` + Nonce string `form:"nonce"` } type OidcDeviceAuthorizationResponseDto struct { diff --git a/backend/internal/model/oidc.go b/backend/internal/model/oidc.go index 3e0cfe2c..7f48d2c6 100644 --- a/backend/internal/model/oidc.go +++ b/backend/internal/model/oidc.go @@ -144,6 +144,7 @@ type OidcDeviceCode struct { DeviceCode string UserCode string Scope string + Nonce string ExpiresAt datatype.DateTime IsAuthorized bool diff --git a/backend/internal/service/oidc_service.go b/backend/internal/service/oidc_service.go index 8253d49c..a1443504 100644 --- a/backend/internal/service/oidc_service.go +++ b/backend/internal/service/oidc_service.go @@ -314,7 +314,7 @@ func (s *OidcService) createTokenFromDeviceCode(ctx context.Context, input dto.O } // Explicitly use the input clientID for the audience claim to ensure consistency - idToken, err := s.jwtService.GenerateIDToken(userClaims, input.ClientID, "") + idToken, err := s.jwtService.GenerateIDToken(userClaims, input.ClientID, deviceAuth.Nonce) if err != nil { return CreatedTokens{}, err } @@ -1282,6 +1282,7 @@ func (s *OidcService) CreateDeviceAuthorization(ctx context.Context, input dto.O ExpiresAt: datatype.DateTime(time.Now().Add(DeviceCodeDuration)), IsAuthorized: false, ClientID: client.ID, + Nonce: input.Nonce, } if err := s.db.Create(deviceAuth).Error; err != nil { diff --git a/backend/resources/migrations/postgres/20260104190900_add_nonce_to_device_codes.down.sql b/backend/resources/migrations/postgres/20260104190900_add_nonce_to_device_codes.down.sql new file mode 100644 index 00000000..6130c122 --- /dev/null +++ b/backend/resources/migrations/postgres/20260104190900_add_nonce_to_device_codes.down.sql @@ -0,0 +1 @@ +ALTER TABLE oidc_device_codes DROP COLUMN nonce; diff --git a/backend/resources/migrations/postgres/20260104190900_add_nonce_to_device_codes.up.sql b/backend/resources/migrations/postgres/20260104190900_add_nonce_to_device_codes.up.sql new file mode 100644 index 00000000..6a1df737 --- /dev/null +++ b/backend/resources/migrations/postgres/20260104190900_add_nonce_to_device_codes.up.sql @@ -0,0 +1 @@ +ALTER TABLE oidc_device_codes ADD COLUMN nonce VARCHAR(255); diff --git a/backend/resources/migrations/sqlite/20260104190900_add_nonce_to_device_codes.down.sql b/backend/resources/migrations/sqlite/20260104190900_add_nonce_to_device_codes.down.sql new file mode 100644 index 00000000..b2f79dba --- /dev/null +++ b/backend/resources/migrations/sqlite/20260104190900_add_nonce_to_device_codes.down.sql @@ -0,0 +1,5 @@ +PRAGMA foreign_keys=OFF; +BEGIN; +ALTER TABLE oidc_device_codes DROP COLUMN nonce; +COMMIT; +PRAGMA foreign_keys=ON; diff --git a/backend/resources/migrations/sqlite/20260104190900_add_nonce_to_device_codes.up.sql b/backend/resources/migrations/sqlite/20260104190900_add_nonce_to_device_codes.up.sql new file mode 100644 index 00000000..793746ed --- /dev/null +++ b/backend/resources/migrations/sqlite/20260104190900_add_nonce_to_device_codes.up.sql @@ -0,0 +1,5 @@ +PRAGMA foreign_keys=OFF; +BEGIN; +ALTER TABLE oidc_device_codes ADD COLUMN nonce TEXT; +COMMIT; +PRAGMA foreign_keys=ON;