Giter VIP home page Giter VIP logo

indiewebkit's Introduction

IndieWebKit

Platform macOS | iOS | iPadOS | tvOS | watchOS SPM compatible License: MIT Build Status Twitter

A Swift Framework for IndieWeb compatible technologies (IndieAuth, Micropub, Microsub). THIS IS CURRENTLY IN DEVELOPMENT AND NOT READY FOR USE.

Author

Eddie Hinkle

License

IndieWebKit is available under the MIT license. See the LICENSE file for more info.

indiewebkit's People

Contributors

edwardhinkle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

indiewebkit's Issues

6.3.1 Generate Token Request

After the state parameter is validated, the client makes a POST request to the token endpoint to verify the authorization code and retrieve the final user profile URL. The POST request contains the following parameters:

grant_type=authorization_code
code - The authorization code received from the authorization endpoint in the redirect
client_id - The client's URL, which MUST match the client_id used in the authorization request.
redirect_uri - The client's redirect URL, which MUST match the initial authorization request.
me - The user's profile URL as originally used in the authorization request

We also want to support PKCE which would include this:
When the client makes a request to redeem the authorization code for an access token, it sends along the original secret that it generated as the code_verifier.

https://indieweb.org/PKCE
https://www.oauth.com/oauth2-servers/pkce/
https://indieauth.spec.indieweb.org/#token-request

5.6 Muting

action=mute

Clients should provide a "mute" option in the interface. This allows the user to mute someone's profile, hiding all posts with the muted user's profile URL as the author from being displayed.

Muting users will cause all posts by the muted user to be hidden from display. The server MAY still store the posts internally, so that un-muting the user will cause past entries to appear again.

Any side effect at the server SHOULD NOT cause the muted user to know they have been muted. Muting users SHOULD NOT have any externally visible side effects.

For example, in the context of the Salmention spec, the server should still behave as if the muted user was not muted.

GET

action=mute
channel={uid}
Retrieve the list of users that are muted in the given channel.

Request

GET /microsub?action=mute&channel=indieweb HTTP/1.1
Response

HTTP/1.1 200 Ok
Content-type: application/json

{
"items": [
{
"type": "card",
"url": "http://annoying.example.com/",
"name": "Annoying Person",
"photo": "http://annoying.example.com/photo.jpg"
},
{
...
}
]
}
POST

action=mute
channel={uid}
url={url}
Mute a user in a channel, or with the uid global mutes the user across every channel.

Request

POST /microsub HTTP/1.1
Content-type: application/x-www-form-urlencoded

action=mute&channel=indieweb&url=https://annoying.example.com/
Response

HTTP/1.1 200 Ok

https://indieweb.org/Microsub-spec#Muting

6.3.5 Token Revocation Function

A client may wish to explicitly disable an access token that it has obtained, such as when the user signs out of the client. IndieAuth extends OAuth 2.0 Token Revocation [RFC7009] by defining the following:

The revocation endpoint is the same as the token endpoint.
The revocation request includes an additional parameter, action=revoke.

As described in [RFC7009], the revocation endpoint responds with HTTP 200 for both the case where the token was successfully revoked, or if the submitted token was invalid.

https://indieauth.spec.indieweb.org/#token-revocation

5.3 Handle Authentication Response Callback

The authorization server will send the response to the callback url which will redirect to the app’s url scheme which will end up in the app’s delegate.

There needs to be a function in the framework that you can call and pass the url that was called and it will finish processing the response.

https://indieauth.spec.indieweb.org/#authentication-response

The redirect is built by starting with the redirect_uri in the request, and adding the following parameters to the query component of the redirect URL:

code - The authorization code generated by the authorization endpoint. The code MUST expire shortly after it is issued to mitigate the risk of leaks. A maximum lifetime of 10 minutes is recommended. See OAuth 2.0 Section 4.1.2 for additional requirements on the authorization code.
state - The state parameter MUST be set to the exact value that the client set in the request.

Upon the redirect back to the client, the client MUST verify that the state parameter in the request is valid and matches the state parameter that it initially created, in order to prevent CSRF attacks. The state value can also store session information to enable development of clients that cannot store data themselves.

See OAuth 2.0 [RFC6749] Section 4.1.2.1 for how to indicate errors and other failures to the user and client.

5.1.3 Remove Entry from a Channel

POST

Parameters:

action=timeline
method=remove
channel={uid}
entry={entry-id} or entry[]={entry-id}
The client can pass one or more entry IDs (found via the _id property on an entry) to remove it from the channel. The server may decide whether to actually delete the entry or just hide it from view. The entry will no longer show up in the given channel's timeline, and this command will not affect the given entry in other channels.

Servers will likely use their own generated IDs for the entry ID, so clients must not make assumptions about the uniqueness of these values.

https://indieweb.org/Microsub-spec#Remove_Entry_from_a_Channel

3.7.3 Syndication Targets Query

To return a list of supported syndication targets, set the q parameter to syndicate-to.

GET /micropub?q=syndicate-to
The endpoint must return the response in [JSON] format, with a key of syndicate-to and the values being objects descriptive of the supported syndication targets. If no endpoints are defined, the value of the syndicate-to object should be an empty JSON array [].

At a minimum, a syndication target must have a uid and human-readable name property. The uid can be any identifier unique to the Micropub endpoint and is not intended to be visible to the end user. The name is intended to be visible to the user in the posting interface, and should be descriptive of the syndication destination.

A syndication target may optionally include additional details about the service or user account at the syndication destination, indicated with a property called service and user respectively. Both service and user objects must contain a name property, intended to be displayed to the user, and may contain a url and photo property. The client can use the name and photo to improve the display of the syndication options to the user.

At a minimum, a syndication destination must have uid and name properties. The uid property is opaque to the client, and is the value the client sends in the Micropub request to indicate the targets to syndicate to. The name property is the value the client can display to the user. The name should be unambiguously descriptive of the destination, so that if for example there are two destinations on the same service, the name can disambiguate them.

The Micropub server may also include additional information about the destination service and user account. This is accomplished with the additional properties service and user, both of which can have three properties, name (a human-readable name), url and photo (both URLs).

The client may use the service and user properties to enhance the display of the syndication options, for example by including the user or service photos on the syndication buttons.

Servers that support syndicating posts should support the syndicate-to query.

Media Endpoint Uploader

There should be an easy function to call with a file or reference to a file that will upload that file to the Media Endpoint.

It should also integrate with #12 so that you can start uploading files and trigger the Micropub Request and the request will wait until these uploads are complete

3.6.2 Authentication
The Media Endpoint must accept the same access tokens that the Micropub endpoint accepts.

3.6.3 Request
To upload a file to the Media Endpoint, the client sends a multipart/form-data request with one part named file. The Media Endpoint may ignore the suggested filename that the client sends.

3.6.4 Response
The Media Endpoint processes the file upload, storing it in whatever backend it wishes, and generates a URL to the file. The URL should be unguessable, such as using a UUID in the path. If the request is successful, the endpoint must return the URL to the file that was created in the HTTP Location header, and respond with HTTP 201 Created. The response body is left undefined.

The Micropub client can then use this URL as the value of e.g. the "photo" property of a Micropub request.

The Media Endpoint may periodically delete files uploaded if they are not used in a Micropub request within a specific amount of time.

3.6.4.1 Media Endpoint Error Response
The Media Endpoint should follow the same conventions for returning error responses as the Micropub endpoint, described in Error Response.

https://micropub.net/draft/#media-endpoint

5.9.4 Reorder Channels

Set Channel Order
Channels are ordered according to the user's preference. When returning the list of channels, the notifications channel must always be the first in the list, as clients are expected to treat it separately such as showing it as a separate icon, not in the main channel list.

To modify the order of channels, the client sends a POST request with a list of channel IDs in the new ordering.

Only the order of the channel IDs specified will be changed. While this command works equally well specifying two, three or more channels, this provides two primary methods for adjusting channel orders.

To move a channel up or down, the client can include the two IDs of adjacent channels in the new desired order.
The client can specify a new ordering for all the channels by providing the full list of channel IDs in the new order.
Request

action=channels
method=order
channels[]={uid}
channels[]={uid}
...
POST /microsub HTTP/1.1
Content-type: application/x-www-form-urlencoded

action=channels
&method=order
&channels[]=2c5e5d7c4d57da68cb03
&channels[]=c972846e827845af974c
Response

HTTP/1.1 200 Ok
Content-type: application/json

https://indieweb.org/Microsub-spec#Set_Channel_Order

6.2.1 Authorization Request

The client builds the authorization request URL by starting with the discovered authorization_endpoint URL and adding the following parameters to the query component:

response_type=code - Indicates to the authorization server that this is an authorization request and an authorization code should be returned
me - The profile URL that the user entered
client_id - The client URL
redirect_uri - The redirect URL indicating where the user should be redirected to after approving the request
state - A parameter set by the client which will be included when the user is redirected back to the client. This is used to prevent CSRF attacks. The authorization server MUST return the unmodified state value back to the client.
scope - (optional) A space-separated list of scopes the client is requesting, e.g. "create". If the client omits this value, the authorization server MUST use a default value

https://indieauth.spec.indieweb.org/#authorization-request

5.8 Blocking

action=block

Blocking users will cause all previous posts by the blocked user to be hidden or deleted, and future posts by that user should not be stored. Additionally, the server SHOULD NOT produce any content or side effect that would notify the blocked user about a post. It is acceptable for the blocked user to know they have been blocked.

For example, in the context of the Webmention spec, the server should not send webmentions even if the user mentions the blocked user in a post. In the context of the Salmention spec, the server should stop sending follow-up webmentions to the blocked user.

GET

action=block
channel={uid}
Retrieve the list of users that are blocked in the given channel.

TODO: document the response format

POST

action=block
channel={uid}
url={url}
Block a user in a channel, or with the uid global blocks the user across every channel.

https://indieweb.org/Microsub-spec#Blocking

6.3.3 Handle Access Token Response

The token response is a JSON [RFC7159] object containing the OAuth 2.0 Bearer Token [RFC6750], as well as a property me, containing the canonical user profile URL for the user this access token corresponds to.

The resulting profile URL MAY be different from what the user initially entered, but MUST be on the same domain. This provides the opportunity to canonicalize the user's URL, such as correcting http to https, or adding a path if required. See Redirect Examples for an example of how a service can allow a user to enter a URL on a domain different from their resulting me profile URL.

See OAuth 2.0 [RFC6749] Section 5.2 for how to respond in the case of errors or other failures.

https://indieauth.spec.indieweb.org/#access-token-response

5.9 List Channels

action=channels

GET

action=channels
Retrieve the list of channels for the user.

The response will contain a channels property with the list of channel uids and names. The uid=notifications channel must always be the first in the list, as clients are expected to treat it separately and not show it in the channel list.

GET /microsub?action=channels
Authorization: Bearer xxxxxxxxx

HTTP/1.1 200 Ok
Content-type: application/json

{
"channels": [
{
"uid": "notifications",
"name": "Notifications",
"unread": 0
},
{
"uid": "31eccfe322d6c48c50dea2c84efc74ff",
"name": "IndieWeb"
"unread": 9
},
{
"uid": "1870e67e924856dc7e4c37732b303b45",
"name": "W3C",
"unread": true
}
]
}
Servers should support tracking the read state of items in channels, and return the number of unread items, or a boolean, when the channel list is queried. If the server does not support read state tracking, then the server must not return the unread property in the response.

For channels that support full unread count tracking, the value of the unread property will be an integer. For channels that support only boolean unread tracking (whether there are new entries or not), the value will be true or false.

https://indieweb.org/Microsub-spec#Channels_2

5.9.3 Delete channel

POST

To create, update, or delete channels, the client sends a POST request with the channels action.

To create a channel, the client includes the name of the channel to create. The uid of the channel will be assigned by the server.

action=channels
name={channel name}
To update a channel, the client includes the uid of the channel to update in the channel parameter, and includes the new name of the channel. Changing the name of the channel MAY change the uid of the channel, and if it does, the server MUST return the new uid in the response.

action=channels
channel={uid}
name={channel name}
To delete a channel, the client includes an additional parameter method=delete. Note that the notifications channel cannot be deleted.

action=channels
method=delete
channel={uid}
Both creating and updating a channel MUST return the uid and name properties for the channel.

Delete a Channel
Request

action=channels
method=delete
channel={uid}
POST /microsub HTTP/1.1
Content-type: application/x-www-form-urlencoded

action=channels
&method=delete
&channel=2c5e5d7c4d57da68cb03c972846e827845af974c9b
Response

HTTP/1.1 200 Ok
Content-type: application/json

https://indieweb.org/Microsub-spec#Delete_a_Channel

Micropub Request function

There should be a function (maybe class?) that receives a Micropub Post struct and uses that to send the post either formencoded or JSON based on the lowest required format. It should also handle knowing if there is a Media Endpoint, and if so, uploading the files there instead of via multipart.

Media Endpoint uploads should have a function that can be triggered while using the posting UI, but it should also be supported that if you call the Micropub create or update function while media endpoint uploads are still running, the framework should see that and set the ACTUAL request to start once the uploads are finished.

There should also be a property that allows a view to know the status ("Uploading", "Sending", etc).

3.1
All Micropub requests to create posts are sent as UTF-8 x-www-form-urlencoded, multipart/form-data [HTML5], or [JSON]-encoded HTTP requests. Responses typically do not include a response body, indicating the needed information (such as the URL of the created post) in HTTP headers. When a response body is necessary, it should be returned as a [JSON] encoded object.

3.1.1 Form-Encoded and Multipart Requests

For x-www-form-urlencoded and multipart/form-data requests, Micropub supports an extension of the standard URL encoding that includes explicit indicators of multi-valued properties. Specifically, this means in order to send multiple values for a given property, you must append square brackets [] to the property name.

For example, to specify multiple values for the property "category", the request would include category[]=foo&category[]=bar.

This works equally well in multipart requests, where each value is given in a separate "part" of the request, and the name is given in a line such as Content-Disposition: form-data; name="category[]".

Note that the extent of the extensions to the x-www-form-urlencoded syntax is the addition of the square brackets to indicate an array. Syntax such as foo[0] and foo[bar] is not supported, and so clients are expected to use the JSON syntax when posting more complex objects.

3.2 Reserved Properties

A few POST body property names are reserved when requests are sent as x-www-form-urlencoded or multipart/form-data.

access_token - the OAuth Bearer token authenticating the request (the access token may be sent in an HTTP Authorization header or this form parameter)
h - used to specify the object type being created
action - indicates whether this is an delete, or undelete (updates are not supported in the form-encoded syntax)
url - indicates the URL of the object being acted on
mp-* - reserved for future use
When creating posts using x-www-form-urlencoded or multipart/form-data requests, all other properties in the request are considered properties of the object being created.

3.3 Create

To create a post, send an HTTP POST request to the Micropub endpoint indicating the type of post you are creating, as well as specifying the properties of the post. If no type is specified, the default type [h-entry] should be used. Clients and servers must support creating posts using the x-www-form-urlencoded syntax, and may also support creating posts using the JSON syntax.

h={Microformats object type}
e.g., h=entry

All parameters not beginning with "mp-" are properties of the object being created.

e.g., content=hello+world

To specify multiple values for a property, such as multiple categories of an h-entry, append square brackets to the property name, indicating it is an array.

e.g., category[]=foo&category[]=bar

Properties that accept multiple values must also accept a single value, with or without the square brackets.

3.3.1 Uploading Files

To upload files, the client must check for the presence of a Media Endpoint. If there is no Media Endpoint, the client can assume that the Micropub endpoint accepts files directly, and can send the request to it directly. To upload a file to the Micropub endpoint, format the whole request as multipart/form-data and send the file(s) as a standard property.

For example, to upload a photo with a caption, send a request that contains three parts, named h, content and photo.

For properties that can accept a file upload (such as photo or video), the Micropub endpoint must also accept a URL value, treating that the same as if the file had been uploaded directly. The endpoint may download [Fetch] a copy of the file at the URL and store it the same way it would store the file if it had been uploaded directly.

3.3.2 JSON Syntax

In order to support more complex values of properties, you can create a post with JSON syntax by sending the entry in the parsed Microformats 2 JSON format.

Note that in this case, you cannot also upload a file, you can only reference files by URL as described above.

When creating posts in JSON format, all values must be specified as arrays, even if there is only one value, identical to the Microformats 2 JSON format. This request is sent with a content type of application/json.

3.3.6 Response

When the post is created, the Micropub endpoint must return either an HTTP 201 Created status code or HTTP 202 Accepted code, and must return a Location header indicating the URL of the created post. [RFC2616]

If the endpoint chooses to process the request asynchronously rather than creating and storing the post immediately, it must return an HTTP 202 Accepted status code, and must also return the Location header. The server must do any error checking and validation of the request synchronously in order to ensure the object will be created successfully, prior to returning HTTP 202. Clients will expect the object at the indicated URL to exist at some point in the (near) future if they receive an HTTP 202 response.

If the target also provides a shortlink, or if it syndicated the post to another location, the Micropub endpoint may return additional URLs using the HTTP Link header, along with an appropriate "rel" value. For example, it can return the short URL of a post by responding with:

Link: http://aaron.pk/xxxxx; rel="shortlink"
or can include the location of the syndicated post with:
Link: https://myfavoritesocialnetwork.example/aaronpk/xxxxxx; rel="syndication"
Error Response

See the "Error Response" section below for details on how to indicate an error occurred.

3.6 Media Endpoint
In order to provide a better user experience for Micropub applications, as well as to overcome the limitation of being unable to upload a file with the JSON syntax, a Micropub server may support a "Media Endpoint". The role of the Media Endpoint is exclusively to handle file uploads and return a URL that can be used in a subsequent Micropub request.

When a Micropub server supports a Media Endpoint, clients can start uploading a photo or other media right away while the user is still creating other parts of the post. The diagram below illustrates a user interface that demonstrates creating a photo post while the photo is uploading asynchronously.

The above user flow applies just as well to mobile apps as it does to desktop apps. In general, the user experience of an application can be improved by having more of the work done asynchronously, giving the user a chance to continue working instead of waiting for the system to finish.

5.5 Unfollow Feed

action=unfollow

POST

action=unfollow
channel={uid}
url={url}
Unfollow a feed from a channel.

POST /microsub
Content-type: application/x-www-form-urlencoded

action=unfollow&channel=indieweb&url=http://tantek.com/
The Microsub server may remove all of this feed's items from the channel, or may leave them in place, at its discretion. If you are used to treating these channels as an IRC or Slack timeline, it would be more appropriate to leave the old items in the channel, just stop delivering new ones. However if you are more used to treating these channels as a Twitter or Facebook feed, then you may want the server to remove them from the channel.

https://indieweb.org/Microsub-spec#Unfollowing

5.9.2 Update Channel

To create, update, or delete channels, the client sends a POST request with the channels action.

To create a channel, the client includes the name of the channel to create. The uid of the channel will be assigned by the server.

action=channels
name={channel name}
To update a channel, the client includes the uid of the channel to update in the channel parameter, and includes the new name of the channel. Changing the name of the channel MAY change the uid of the channel, and if it does, the server MUST return the new uid in the response.

action=channels
channel={uid}
name={channel name}
To delete a channel, the client includes an additional parameter method=delete. Note that the notifications channel cannot be deleted.

action=channels
method=delete
channel={uid}
Both creating and updating a channel MUST return the uid and name properties for the channel.

Update a Channel
Request

action=channels
channel={uid}
name={channel name}
POST /microsub HTTP/1.1
Content-type: application/x-www-form-urlencoded

action=channels
&channel=2c5e5d7c4d57da68cb03c972846e827845af974c9b
&name=Friends
Response

HTTP/1.1 200 Ok
Content-type: application/json

{
"uid": "2c5e5d7c4d57da68cb03c972846e827845af974c9b",
"name": "Friends"
}

https://indieweb.org/Microsub-spec#Update_a_Channel

5.4 Follow Feed

action=follow

GET

action=follow
channel={uid}
Retrieve the list of feeds being followed in the given channel.

Response

{
"items": [
{
"type": "feed",
"url": "http://tantek.com/"
}
]
}
The feed items may contain additional properties that describe the feed, see http://microformats.org/wiki/h-feed.

POST

Follow a new URL in a channel.

action=follow
channel={uid}
url={url}
POST /microsub
Content-type: application/x-www-form-urlencoded

action=follow&channel=indieweb&url=http://tantek.com/
When a request to the follow endpoint is made, the Microsub server registers the follow action, and begins delivering content at that URL into the channel. The Microsub server can subscribe to the target URL via any mechanism available, but most often will attempt a WebSub subscription for its HTML+Microformats, or Atom/RSS feed, and fall back to polling if that fails.

New entries at the followed URL will appear in the channel when fetched from the channel's timeline. The Microsub server may fetch existing entries in the feed and add them to the channel at its discretion.

The response is a JSON representation of the channel, the same as is returned when listing all feeds followed in a channel.

{
"type": "feed",
"url": "http://tantek.com/"
}

https://indieweb.org/Microsub-spec#Following

3.4 Add support for updating posts

Micropub servers should support updating posts, including adding and removing individual properties as described in this section.

Updating entries is done with a JSON post describing the changes to make.

To update an entry, send "action": "update" and specify the URL of the entry that is being updated using the "url" property. The request must also include a replace, add or delete property (or any combination of these) containing the updates to make.

The values of each property inside the replace, add or delete keys must be an array, even if there is only a single value.

While it is okay to combine add/delete operations in the same request, it only makes sense to do so when they are operating on different property-value combinations. Servers may have undefined behavior if multiple operations of the same property-value combination are sent in an update request.

3.4.1 Replace

Replace all values of the property. If the property does not exist already, it is created.

This will replace the entire entry content with the new text, leaving any other existing property of the post as is.

3.4.2 Add

If there are any existing values for this property, they are not changed, the new values are added. If the property does not exist already, it is created.

Adding a syndication URL

Use case: adding a syndication link to a post after it has been published. For example, when a client supports posting first then syndicating to MyFavoriteSocialNetwork or Wikimedia after the fact, the site needs a way to update the original post with the new syndication URL.

To add syndication URLs, include one or more URLs in the update request.

3.4.3 Remove

If the property exists, remove it. This completely removes the specified property.

For properties with multiple values, such as categories, you can remove individual entries by value. If no values remain, the property is removed.

3.4.4 Response

The server must respond to successful update requests with HTTP 200, 201 or 204. If the update operation caused the URL of the post to change, the server must respond with HTTP 201 and include the new URL in the HTTP Location header. Otherwise, the server must respond with 200 or 204, depending on whether the response body has content. No body is required in the response, but the response may contain a JSON object describing the changes that were made.

5.2 Initiate Authentication Request

There needs to be a function that an App can call within IndieWebKit that builds and makes the Authentication Request. It will need to be able to customize the callback per app.

The client builds the authentication request URL by starting with the discovered authorization_endpoint URL and adding the following parameters to the query component:

me - The user's profile URL
client_id - The client URL
redirect_uri - The redirect URL indicating where the user should be redirected to after approving the request
state - A parameter set by the client which will be included when the user is redirected back to the client. This is used to prevent CSRF attacks. The authorization server MUST return the unmodified state value back to the client.
response_type=id - (optional) Indicates to the authorization server that this is an authentication request. If this parameter is missing, the authorization endpoint MUST default to id.

https://indieauth.spec.indieweb.org/#authentication-request

3.7.2 Add support for Querying Post Content

3.7.2 Source Content
A Micropub client can query the endpoint to return specific properties of a post. This allows a client to request only the properties it needs or knows about, supporting such uses as making an interface to add tags to a post.

Servers that support updating posts must support the source content query.

To query, make a GET request to the Micropub endpoint and set the q parameter to source, and include the URL of the post in the url parameter. The query can specify the list of properties being requested by setting one or more values for the properties key. If more than one is specified, use array bracket notation for each name, according to [HTML5] URL encoding.

The endpoint must return the response in [microformats2-parsing] [JSON] format, with an object named properties, where the keys are the names of the properties requested. If no properties are specified, then the response must include all properties, as well as a type property indicating the vocabulary of the post.

HTML Content
If the source of the post was written as HTML content, then the endpoint must return the content property as an object containing an html property. Otherwise, the endpoint must return a string value for the content property, and the client will treat the value as plain text. This matches the behavior of the values of properties in [microformats2-parsing].

Below is an example of requesting the content of a post which was authored as HTML.

https://micropub.net/draft/#source-content

6.2.2 Handle Authorization Response

Using the ASWeb-OAuth thing, we should be able to have this function automatically called.

The redirect is built by starting with the redirect_uri in the request, and adding the following parameters to the query component of the redirect URL:

code - The authorization code generated by the authorization endpoint. The code MUST expire shortly after it is issued to mitigate the risk of leaks. A maximum lifetime of 10 minutes is recommended. See OAuth 2.0 Section 4.1.2 for additional requirements on the authorization code.
state - The state parameter MUST be set to the exact value that the client set in the request.

Upon the redirect back to the client, the client MUST verify that the state parameter in the request is valid and matches the state parameter that it initially created, in order to prevent CSRF attacks. The state value can also store session information to enable development of clients that cannot store data themselves.

See OAuth 2.0 [RFC6749] Section 4.1.2.1 for how to indicate errors and other failures to the user and client.

https://indieauth.spec.indieweb.org/#authorization-response

Think through how to support Low Data Mode

in iOS 13, Apple is introducing Low Data Mode. For large or prefetch data sets, you should allowsContrainedNetworkAccess = false. Need to think through how and when this should be set through the framework.

5.4 Authorization Code Verification

After the state parameter is validated, the client makes a POST request to the authorization endpoint to verify the authorization code and retrieve the final user profile URL. The POST request contains the following parameters:

code - The authorization code received from the authorization endpoint in the redirect
client_id - The client's URL, which MUST match the client_id used in the authorization request.
redirect_uri - The client's redirect URL, which MUST match the initial authorization request.

If the request is valid, then the endpoint responds with a JSON [RFC7159] object containing one property, me, with the canonical user profile URL for the user who signed in.

The resulting profile URL MAY be different from what the user initially entered, but MUST be on the same domain. This gives the authorization endpoint an opportunity to canonicalize the user's URL, such as correcting http to https, or adding a path if required. See Redirect Examples for an example of how a service can allow a user to enter a URL on a domain different from their resulting me profile URL.

See OAuth 2.0 [RFC6749] Section 5.2 for how to respond in the case of errors or other failures.

https://indieauth.spec.indieweb.org/#authorization-code-verification

3.5 Should add a function to delete/undelete a post

3.5 Delete

Micropub servers should support deleting posts, and may support undeleting posts.

To delete an entire entry at a URL, send a POST request containing action=delete and the URL of the item in the url property.

To undelete a post, use "undelete" as the action.

3.5.1 Response

The server must respond to successful delete and undelete requests with HTTP 200, 201 or 204. If the undelete operation caused the URL of the post to change, the server must respond with HTTP 201 and include the new URL in the HTTP Location header. Otherwise, the server must respond with 200 or 204, depending on whether the response body has content. No body is required in the response, but the response may contain a JSON object describing the changes that were made.

5.2 Search for Feeds

action=search

The "search" action exists to provide a UI for the server to respond with the full URL of possible things to subscribe to. For example, a user should not be expected to type the exact URL of a feed to subscribe to, but instead should be able to enter partial matches, e.g. entering aaronparecki.com should return the full URL of https://aaronparecki.com/.

Using the "search" action, a client can provide a single text field where the user can enter either partial URLs or even arbitrary search terms, and the server can reply with a list of URLs that can actually be subscribed to. This also provides the ability to have a confirmation step where users can see a preview of what they will be subscribing to before they actually do so.

If the search term is a URL or partial URL, the Microsub server SHOULD fetch the URL if not already known, and discover any feeds at that URL that can be subscribed to. The server may also return feeds that are already known that match the search term, for example if another user on the server has previously subscribed to a matching URL.

POST

Request

action=search
query=

The response results are a jf2 version of the h-feed vocabulary. The only required properies are the type and URL.

type - (required) feed
url - (required) the URL of the result which can be used in a follow action to follow the feed
name - the display name of the feed
photo - a photo or icon representing the feed
description - a description of the feed, either as reported by the feed or generated by the Microsub server
author - a jf2 h-card describing the author of the feed. For multi-author feeds this may be an h-card representing the organization, or may be omitted

https://indieweb.org/Microsub-spec#Search

5.9.1 Create Channel

To create, update, or delete channels, the client sends a POST request with the channels action.

To create a channel, the client includes the name of the channel to create. The uid of the channel will be assigned by the server.

action=channels
name={channel name}
To update a channel, the client includes the uid of the channel to update in the channel parameter, and includes the new name of the channel. Changing the name of the channel MAY change the uid of the channel, and if it does, the server MUST return the new uid in the response.

action=channels
channel={uid}
name={channel name}
To delete a channel, the client includes an additional parameter method=delete. Note that the notifications channel cannot be deleted.

action=channels
method=delete
channel={uid}
Both creating and updating a channel MUST return the uid and name properties for the channel.

Create a Channel
Request

action=channels
name={channel name}
POST /microsub HTTP/1.1
Content-type: application/x-www-form-urlencoded

action=channels&name=Coworkers
Response

HTTP/1.1 200 Ok
Content-type: application/json

{
"uid": "2c5e5d7c4d57da68cb03c972846e827845af974c9b",
"name": "Coworkers"
}

https://indieweb.org/Microsub-spec#Create_a_Channel

Micropub Configuration Request

You should be able to create a Micropub config request.

When a user initially logs in to a Micropub client, the client will want to query some initial information about the user's endpoint. The client should make a query request q=config to obtain initial configuration information.

Things it should look for:

5.1.2 Mark Entries Read

POST

To mark one or more individual entries as read or unread:

Parameters:

action=timeline
method=mark_read (or mark_unread)
channel={uid}
entry={entry-id} or entry[]={entry-id}
To mark an entry read as well as everything before it in the timeline: (does not apply to mark_unread)

action=timeline
method=mark_read
channel={uid}
last_read_entry={entry-id}
These commands only affect the entry within the context of the given channel's timeline, and do not affect other timelines.

https://indieweb.org/Microsub-spec#Mark_Entries_Read

5.3 Preview Feed

action=preview

POST

action=preview
url={url}
The "preview" action exists so that the client can display a preview of a URL to the user before the user wants to create a subscription for it. The preview should show as much about the URL as the server can determine, such as basic profile information about the user, and a few recent entries by the user. There should be no permanent side effects created by previewing a URL, and as much as possible, the URL being previewed should not be provided with identifying information of the user who is previewing the URL.

The response includes the list of items in the feed if available, in the same format as returned by the #Timelines API call.

https://indieweb.org/Microsub-spec#Preview

Some test cases for IndieAuth Profile redirects

4.1.1 Redirect Examples

4.1.1.1 http to https

In this example, the user enters example.com in the sign-in form, so the client initially transforms that to http://example.com/ to perform discovery. The URL http://example.com/ returns an HTTP 301 permanent redirect to https://example.com/, so the client updates the initial profile URL to https://example.com/, and looks at the contents of that page to find the authorization endpoint.

4.1.1.2 www to no-www

In this example, the user enters www.example.com in the sign-in form, so the client initially transforms that to http://www.example.com/ to perform discovery. The URL http://www.example.com/ returns an HTTP 301 permanent redirect to https://example.com/, so the client updates the initial profile URL to https://example.com/, and looks at the contents of that page to find the authorization endpoint.

4.1.1.3 Temporary Redirect

In this example, the user enters example.com in the sign-in form, so the client initially transforms that to http://example.com/ to perform discovery. The URL http://example.com/ returns an HTTP 301 permanent redirect to https://example.com/, and https://example.com/ returns an HTTP 302 temporary redirect to https://example.com/username. The client stores the last 301 permanent redirect as the profile URL, https://example.com/, and uses the contents of https://example.com/username to find the authorization endpoint.

4.1.1.4 Permanent Redirect to a Different Domain

In this example, the user enters username.example in the sign-in form, so the client initially transforms that to http://username.example/ to perform discovery. However, the user does not host any content there, and instead that page is a redirect to their profile elsewhere. The URL http://username.example/ returns an HTTP 301 permanent redirect to https://example.com/username, so the client updates the initial profile URL to https://example.com/username when setting the me parameter in the initial authorization request. At the end of the flow, the authorization endpoint will return a me value of https://example.com/username, which is not on the same domain as what the user entered, but the client can accept it because of the HTTP 301 redirect encountered during discovery.

4.1.1.5 Temporary Redirect to a Different Domain

In this example, the user enters username.example in the sign-in form, so the client initially transforms that to http://username.example/ to perform discovery. However, the user does not host any content there, and instead that page is a temporary redirect to their profile elsewhere. The URL http://username.example/ returns an HTTP 302 temporary redirect to https://example.com/username, so the client discovers the authorization endpoint at that URL. Since the redirect is temporary, the client still uses the user-entered http://username.example/ when setting the me parameter in the initial authorization request. At the end of the flow, the authorization endpoint will return a me value of https://username.example/, which is not on the same domain as the authorization endpoint, but is the same domain as the user entered. This allows users to still use a profile URL under their control while delegating the authorization flow to an external account.

https://indieauth.spec.indieweb.org/#redirect-examples

3.3.3 See if there is a way to avoid nested post objects in storage

3.3.3 Nested Microformats Objects

Whenever possible, nested Microformats objects should be avoided. A better alternative is to reference objects by their URLs. The most common example is including an h-card for a venue, such as checking in to a location or tagging a photo with a person or location. In these cases, it is better to reference the object by URL, creating it first if necessary.

This technique has the advantage of ensuring that each object that is created has its own URL (each piece of data has its own link). This also gives the server an opportunity to handle each entity separately. E.g., rather than creating a duplicate of an existing venue, it may give back a link to one that was already created, possibly even merging newly received data first.

In some cases, it does not make sense for the nested object to have a URL. For example, when posting an h-measure value, there is no reason for the h-measure itself to have a URL, so this is an acceptable case to use the nested Microformats object syntax.

Nested objects require that the request be sent in JSON format, since the form-encoding syntax does not consistently support nested objects.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.