Skip to content

Account activation should use path parameter instead of JSON body on GET #8

@fupelaqu

Description

@fupelaqu

Problem

The activate endpoint in AccountServiceEndpoints uses securityIn(jsonBody[Activate]) on a GET request:

val activate: ServerEndpoint[Any with AkkaStreams, Future] =
    setNewCsrfToken(checkMode) {
      setSession(sc, st) {
        endpoint
          .securityIn(jsonBody[Activate])  // <-- JSON body on GET
          ...
      }
    }
      .in(AccountSettings.Path / "activate")
      .get

This is problematic because:

  1. GET requests should not have a body — per HTTP spec (RFC 7231), GET semantics are defined for retrieval and request bodies have no defined semantics
  2. Browsers cannot send GET with JSON body — activation links in emails (/activate?token=...) cannot work directly
  3. InconsistencycheckResetPasswordToken correctly uses path[String] for the same pattern (token in URL path)

Proposed Fix

Change activate to use path[String] (consistent with checkResetPasswordToken):

val activate: ServerEndpoint[Any with AkkaStreams, Future] =
    setNewCsrfToken(checkMode) {
      setSession(sc, st) {
        endpoint
          .errorOut(ApiErrors.oneOfApiErrors)
          .serverSecurityLogicWithOutput(activate =>
            run(activate.token, activate).map {
              ...
            }
          )
      }
    }
      .in(AccountSettings.Path / "activate")
      .in(path[String])
      .get

Route: GET /account/activate/{token} (instead of GET /account/activate with JSON body)

Analysis of Other Endpoints

Review of all endpoints in AccountServiceEndpoints for similar issues:

Endpoint Method Input Assessment
signUp POST jsonBody[SU] OK — POST with body
login/signIn POST jsonBody[Login] OK — POST with body
activate GET jsonBody[Activate] BUG — should be path[String]
basic POST auth.basic[UsernamePassword] OK — Basic auth header
principal POST jsonBody[UpdateLogin] OK — POST with body, authenticated
logout/signOut POST (no body) session only OK
sendVerificationCode POST jsonBody[SendVerificationCode] OK — POST with body
sendResetPasswordToken POST jsonBody[SendResetPasswordToken] OK — POST with body
checkResetPasswordToken GET path[String] OK — correctly uses path param
resetPassword POST jsonBody[ResetPassword] OK — POST with body
unsubscribe POST session only OK
registerDevice POST jsonBody[DeviceRegistration] OK
unregisterDevice DELETE path[String] OK
updatePassword POST jsonBody[PasswordData] OK

Only activate has this issue. All other GET endpoints correctly use path parameters.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions