Support for creating an App and logging in to a server.
Get a token and, if possible, the logged in Account from the server.
The Maybe String arg is a login token, called maybeToken below, if
it is not Nothing.
Returns a Task to either fetch an Account for a known authorization token,
or to redirect to the authentication server to create a code with which
to mint the token.
If maybeToken is not Nothing, will attempt to get an
Account using that token. If that fails, will
return an error. If maybeToken is Nothing, will create a new App, and
redirect to do authentication. When the application is restarted, with
a code and state in the URL query, call getTokenTask to
use those to mint a new token, and to use that to get an Account.
Usually, you will get a Token from persistent
localStorage, pass that here, and successfully receive the Account
back. No redirects necessary. But the redirects must happen at least
once, and then whenever the authorization token expires. This is step
8 below. Only if that fails will this do step 3, or, if there was no
persisted client id and secret, steps 1 through 3.
Currently, permission for all scopes is requested. Maybe the scopes should be passed as a parameter.
The full login procedure is as follows:
Send "POST /api/v1/apps" to the Mastodon server, via a PostApp request.
Receive the returned client_id and client_secret
Redirect to <server_url>/oauth/authorize?client_id=<client_id>&redirect_uri=<client_uri>&response_type=code&scope=<scopes>&state=<state>
The user enters login authorization information to the server web site.
The server web site redirects to <redirect_uri>?code=<code>&state=<state>
The <state> encodes the server uri, <client_id>, <client_secret>, and <scopes>.
Use that to POST to <server_url>/oauth/token:
POST /oauth/token HTTP/1.1
Host: <server_url>
Authorization: Basic `(Base64.encode (<client_id> ++ ":" ++ <client_secret>))`
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=<code>&redirect_uri=<client_uri>Receive back token information, JSON-encoded:
{ "access_token":"cptLSO8ff7zKbBXlTTyH15bnxQS5b9erVUWi_n0_EGd",
"token_type":"Bearer",
"scope":"write,read,follow,push"
"created_at":1561845912
}Use the token_type and access_token to authenticate a request
for the user's Account.
Continue after being restarted with a code and state in the URL query.
This continues from step 6 in the full login procedure description,
which is included with the documentation for loginTask above.
Your application will usually persist the Authorization, so you can use it
the next time the user starts the application, as a parameter to loginTask.
The String in the Task is the server name, e.g. "mastodon.social".
Convert a server domain and a Mastodon.Entity.App into a state string.
You will rarely, if ever, call this explicitly. It is exposed for debugging.
Decode the string created by encodeStateString.
You will rarely, if ever, call this explicitly. It is exposed for debugging.
Compute URL to redirect to for authentication.
Args are:
appToAuthorizeUrl server appReturns:
https://<server>/oauth/authorize
?client_id=<app.client_id>
&redirect_uri=<app.redirect_uri>
&response_type=code
&scope=<all scopes>
&state=<encodeStateString server app>You will call this only when a token expires, and you need to mint a new one
from a previously created App:
appToAuthorizeUrl server app
|> Browser.Navigation.load
The result type of the
loginTaskfunction.It's either a task to fetch the logged-in user's
Mastodon.Entity.Accountor a task to redirect to the authorization server to get a code.The two
Strings inFetchAccountare the server name and token. TheStringinRedirectis the server name.