The final three fields to implement for the defaultCloud function relate to handling the response from the identity provider and creating the session type that parameterizes the Auth ability. Once the user successfully signs in, the auth provider sends the app a response containing a token representing the user's identity.

Your task is to tell the app how to transform this TokenResponse into the session type in the onSuccess callback function.

[...]
onSuccess : TokenResponse IdToken ->{Exception, Http, Log} ex4_oauth.UserId
onSuccess = todo "successCallback"
decodeSession : '{Decoder} ex4_oauth.UserId
decodeSession = todo "decodeSession"
encodeSession : : ex4_oauth.UserId -> Json
encodeSession = todo "encodeSession"

We've decided that the "session" type is a UserId: a simple wrapper around a Text id value, but if our model of a "signed in user" needed more information, such as the user's email, we could also extract that information from the TokenResponse.

As a heads up, not every OAuth provider returns an IdToken in the TokenResponse. Github and Twitter, for example, require that the user use the AccessToken from the response to issue another request to their api. In this case, the onSuccess function would include an http request to get the UserId.

The JSON encoder and decoder functions are used by the Auth library when saving the session type as a cookie in the browser.

📓 Instructions

Implement the onSuccess callback function. Its argument, TokenResponse IdToken, is a wrapper around a text value representing a JWT.

The onSuccess function should do the following:

  • Decode the JWT text into a JWT type with the jwt_0_0_1.decode function
  • Extract the sub value from it with Jwt.sub. (Remember that value from our scopes configuration step? 😉) This is the unique user id for the identity provider
  • Use the sub value to create an instance of the ex4_oauth.UserId type

Finally, use the JSON library to write the encodeSession and decodeSession functions. They should encode and decode the ex4_oauth.UserId into a json object which looks like this:

{
  "user_id": "unique-user-id-as-string"
}

At this point, your defaultCloud function should have all its arguments implemented. You've made your AuthConfig type! The hard part is done! 🚀