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 in
the URL query, call getTokenTask to use that code and the saved
App instance 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 App, including client_id and client_secret.
Save it in localStorage, keyed with the Mastodon server's host name
(from applicationUri).
Redirect to <server_url>/oauth/authorize?client_id=<client_id>&redirect_uri=<applicationUri>&response_type=code&scope=<scopes>
The user enters login authorization information to the server web site.
The server web site redirects to <applicationUri>?code=<code>
Lookup the saved App instance using the Mastodon server's host name
(which your top-level application must persist somewhere).
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=<applicationUri>&client_id=<client_id>&client_secret=<client_secret>The Authorization header isn't needed for new Mastodon API servers,
but that's how it was done for old ones, so I'm hoping this will give
some backward compatibility.
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".
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>You will call this explicitly 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.