[KevinMarks]twitter no longer has hcards for contacts, technorati no longer has the hcard to vcard converter, plaxo no longer converts vcards to portable contacts, and jsontoxoxo is now on unmung
Loqi[DoctorMac] @lukeboch and @manton I asked on indieweb chat. You could use unmung to turn the rss feed into an html feed and then granary.io to turn hfeed into json feed....I betchya results somewhere from broken to ugly but worth a shot
barnabySaphire: yes, that’s correct, as IA is defined right now, the authorization endpoint needs to implement both a user-facing authorization flow, and an app-facing auth code redeeming flow
barnabyit’s a back-compat thing held over from older versions of indieauth, and is not compatible with OAuth2. there’s been some discussion about deprecating it, but for the moment it’s still part of the spec
barnabywell depending on your needs, you can choose to pre-emptively deprecate it yourself :) I don’t think there’s a list of which clients rely on that feature
barnabyhave a function which accepts an HTTP request object and returns an HTTP response. if the request is an auth code redeeming request, pass it off to the auth token redeeming logic. otherwise, pass it off to the authorization flow logic, wrapped in a CSRF middleware
ZegnatI am not sure about the “not compatible with OAuth2” though. Why do you think that, barnaby? That would be a great reason to deprecate it ASAP too. But as I understand it, OAuth2 does not specify any preferences as far as which endpoints do what, and it is completely fine even to have auth and token endpoint be the exact same URL always.
barnabyI admit that I’ve not read the entire OAuth2 spec, but interpreted the first paragraph of that issue you linked as IA not being compatible/compliant/consistent due to a) allowing empty scope and b) allowing access tokens to be redeemed at the authorization endpoint
ZegnatOr well, not super confusing I was there for a lot of the spec writing talks, but maybe not super clear on the whole different-scopes-different-endpoints thing
barnabyI think the auth endpoint scopeless token redeeming was kept in a) for back-compatbility and b) because people wanting to have a server which just authenticates them, and doesn’t grant a token, is quite a common use-case
barnabyso, the token_endpoint only has one flow, a POST request with authorization code details, which get verified. It returns a JSON response containing either access token details, or an error
barnabyan authorization request flow, which is a GET request which the user was redirected to from their client app. the query string contains various parameters pertaining to the request. This flow needs to check that the user is logged in, redirect them to a login flow if not, and then finally return a consent/scope-granting form response on a logged-in request
barnabythe final flow is a POST request containing the consent/scope-granting form submission, which needs to check validity, build an access_code and return a redirect back to the client app’s redirect_uri with code and state details
barnaby(technically, the final flow could potentially be implemented at a different endpoint if you want, but I found it easiest to just re-use the authorization endpoint for it)
SaphireBut yeah I'm trying to implement it in a very type safe language. And it's very, very easy to make an endpoint that will take in a specific object constructed from params
barnabyand then within that, you detect the nature of the response, maybe build a query object from the HTTPRequest specific to the detected flow, and pass that off to a dedicated function
barnabyI do have one callback function which can choose to return either a pre-made HTTPResponse object or authentication data, but in rust I would just use an enum and it’d be totally type-safe
barnabyyeah, there’s a fair amount of state to keep track of, and complications with handing a logged-out request off to a login route and then seamlessly restarting the indieauth request
barnabyalso IMO there’s a bunch of stuff on that page which has little to do with the auth endpoint and needs to either be removed or clarified, e.g. the stuff about the sign-in form
Zegnatbarnaby: I am not sure if I agree with "consent form submission" as a flow. That is an implementation detail, and is also why it is not included in the spec (or in any OAuth spec).
barnabythere’s not much point having /authorization_endpoint just repeat what’s in the spec. IMO it’s better put to use as a practical implementation guide
ZegnatThe only two flows that MUST be supported are accepting a GET request that (in happy flow) results in a redirect back, and accepting a POST request that (in happy flow) results in a Profile URL Response
Zegnatbarnaby: I agree , for implementation guide. I just wanted to be a stickler and point out that there are really only 2 possible incoming requests that you MUST support for the spec. And those two can actually be split based on HTTP method already and you do not need to inspect parameters for it
ZegnatIt is for instance completely fine (if it is easier for the implementation) to redirect the user to an entirely different endpoint for showing the consent form.
mgdmFastly's official line is "We experienced a global outage due to an undiscovered software bug that surfaced on June 8 when it was triggered by a valid customer configuration change."
ZegnatSo if, completely hypothetical because I do not know, Saphire’s problem is with inspecting query params, it is completely fine to skip that entirely. Check if the incoming request to the authorization endpoint is a GET or a POST, after that you know exactly what the possible set of parameters is.
ZegnatThe consent form could be fully JS based for all I know, and talk with an endpoint on an entire different domain. That is why I do not like to generalise about it, and is why OAuth makes it an implementation detai
barnabyalso, while it is in theory currently possible to determine which flow is happening based on the method, in practise it’s also necessary to inspect the query params (response_type=code, specifically)
Zegnat? Not really? If you are doing a GET, you can assume that response_type=code is set. In fact, you should immediately stop the process if it is not.
ZegnatSo you can make the call based on HTTP method, if it is a GET, you probably want to validate the params so you can exit early if it is not a valid OAuth request, but at that point you have already determined the type of request based on the method. (Which I thought the issue here was.)
ZegnatWhen a client makes a GET request against the authorization endpoint, it expects to be redirected back to a URL it provided in that GET request. Any pages (or none) you chose to show in between is up to you.
barnabyyep, which is described well by the spec, but at /authorization-endpoint I want to help people actually build practical endpoints, which involves some non-generic implementation details
ZegnatYeah, I can see how that is not really clear everywhere. I guess I am just a stickler on the fact that none of those details should be covered by the IndieAuth spec (wich is an extension to OAuth 2.0) because it can and will vary wildly between platforms.
ZegnatI think that node one is based on the PHP selfauth one. It uses the exact same logic for checking state values, with the exact same function names, haha
ZegnatI wonder why it does that. It is not good code. We used md5 as a lowest common denominator for old PHP versions. Node.js should have been able to do better
Zegnatbarnaby: PHP one does that too. But that might have been because the signed codes part that adds time-to-live was added later and we did not want to break existing setups with md5 passwords.
Zegnatselfauth has done pretty well as a reference implementation for people, I believe. And most of the error checking is super solid. But for the actual hashing stuff it is showing its age
ZegnatThe part that there were 2 different flows for authentication and authorization is why we are stuck with authorization endpoint having to handle code exchanges
ZegnatNote that it is an implementation of an older spec version though. As it needs to be able to contact the authorization endpoint to see if a token should be issued
SaphireSo for security uh. I should only let the GET /auth_endpoint to only redirect to actual page, one which is set to Allow-Origin only of the auth site?
SaphireSo it goes.. client -> /auth_endpoint with query of {me, redirect_url, client_id, ...}, Then auth endpoint does a redirect or in any other way goes through an authentication and authorization flow, the entire flow resulting (on success) in redirect to redirect_url and query params of code and state, where state is original state supplied to endpoint and code is an opaque token that can be
Saphire...and a separate flow of {code, redirect_url, client_id} to same endpoint where it checks the token (in opaque way) and just goes nah, or ok and gives user info?
ZegnatIf this POST went to the authorization endpoint it will result in either HTTP 200 response with a JSON body { me[, profile] } or HTTP 400 with a JSON body according to OAuth rfc 6749 with error information
ZegnatFor stateless clients, you can store it inside the "state" value, but in that case have to make sure it cannot be extracted from it, e.g. by encrypting the state payload
barnabyso, my server library currently includes an unencrypted form of the code_challenge in any intermediate requests during the authentication and consent screen flow
ZegnatThey probably mean that you should not put the challenge next to the code, as the point of the challenge is that only the original requestee knows which code goes with which challenge and you want to keep it that way
aaronpkand also from earlier, I am all in favor of making the wiki pages more of an implementation guide, calling out things that aren't appropriate to put in the actual spec. but it would also be useful to highlight that those things are still implementation details
barnabyso that there’s a summary of both on the same page, and so that there’s a structure for adding alternative implementation-specific flow suggestions which still comply with the general spec flow
ZegnatJust when servers are on the web, and the front-facing part of authentication and consent screen are handled by them, it starts to blur the lines a little, as the majority of the people implementing the server side of the spec will also need to implement all those unspeced things
ZegnatThat might be a more illustrative way of thinking, yes. It is definitely laid out that way. Though you can read it as the server’s point of view by treating the spec as being “in the likely order of requests send to me by a client”
SaphireI kinda need to get indieauth working on my site to get to wiki, oooor remove the <link>s for indieauth leading to nothing. Actually invalid nothing, even
SaphireI am assuming that authorization_endpoint returned code is basically just a temporary opaque thing (that is sufficiently non-predictable to not let people guess it!) that only lives for like, a minute or something?
barnabyand according to the spec it MUST only be usable once, which means you either have to persist them somewhere and delete/expire them after they’re exchanged, OR keep track of which ones have been exchanged in your list of access tokens and check against that
SaphireBuuut you can have a small vector/table/object/etc in your persistently running server app (unless you are on something more per-request like PHP where you'll need to use a DB or other value store) that would be cleaned out from say, entries older than 5 minutes
ZegnatI think that is something like how I do it, I would have to double check. I actually store the one-time opaque codes in the db, and have all the important client details associated with it.
ZegnatWhen the client then comes to exchange the code for a token, that token is added to the same database record, turning the code storage into a token storage. Codes are automatically one-time-use, because on second try I see the token field is already filled.
ZegnatThe stateless way is what the previously linked endpoints do, where they put all that information into the code itself encoded/signed/encrypted in some way. Which is also fine, but I found that to be more overhead in the longrun than depending on an SQLite file
ZegnatI think some applications just bite the bullet on that if they must be stateless. So they set a short TTL on the code and assume that to be reliable enough *shrug*
ZegnatAs long as the code can only have been generated by you (because it ensures the user has consented) it can be anything. Randomness is not a concern.
sknebelfor large systems there is some argument that it might be easier to keep and check a small revocation list on each node than always querying a DB of all tokens
ZegnatStateless always sounds fun when it is described as “look mum, no datatabase”, but then when you actually start implementing a full authorization flow and find out you need to bring in encryption to hide things from clients, keep track of ttls, etc., it is no longer as fun ;)
Saphire> Using a common data format allows for easy interoperability with established solutions. It is perfectly fine to develop your own token solution (as long as you don’t roll your own crypto). However, JWTs are the established solution, and you can’t go wrong with them.
ZegnatSpecifically on indieweb.org ? aaronpk might have those. Or maybe not. We are pretty statistics-lite in general on IndieWeb things. Wouldn’t want to do too much tracking
[tantek]hey snarfed, does granary support consuming h-feed h-entry u-featured images and converting them to some equivalent in Atom? That is, how do you publish featured images in Atom? perhaps <entry><link rel="featured" href="image.jpg" /> ?
Loqifeatured is a proposed mf2 property (typically as u-featured) for h-entry that indicates a representative image for a post https://indieweb.org/featured
[tantek]somewhat related, are folks using any kind of markup to express their "related posts" or "related articles" that they link to from a specific article/post?
[tantek]e.g. the "obvious" "simple" thing in plain HTML would be rel="related", but I'm not sure that's the best for structure inside an h-entry. I could see a u-related-entry property, but wanted to first check to see what people's existing publishing did.
[tantek]or if other formats have something already, e.g. does Atom have a notion of <link rel="related" href="article.html" /> that you could put inside an <entry> ?
[tantek]it's too bad the atom:icon element is only specified as a child of <feed>, missed opportunity there to re-use that for <entry> as a way to do a featured/preview image for an entry
[Murray], shoesNsocks and [snarfed] joined the channel
[snarfed]sure! I’m open to all of those. I don’t really follow a lot of markup semantics like those, so I’m probably not the best person to lead any changes, but I’m happy to review and merge!
[tantek]closest hack might be to use atom:contributor element, with a uri, and then if that uri prefix matches the permalink of the entry, then that contributor can be determined to be the "publisher"
barnaby[tantek]: re “uses CDATA for content 🙄”, what’s wrong with that if you’re publishing HTML content which would result in invalid XML if included directly in the ATOM feed? e.g. valid HTML5 void elements like <br> or <img>?
[snarfed]in some cases yes, but not always easily. eg granary uses CDATA because it sometimes has to to pass through arbitrary input HTML content, and I don’t really want to try to parse that, regenerate it as XHTML5, and handle the 50 resulting cases of lossiness and other bugs that would happen
barnaby[snarfed]: do you search the 3rd party content for CDATA closing tags? what would happen if some of the arbitrary HTML content included one and prematurely ended the CDATA section?
barnabyI suppose the only guaranteed-non-fragile method would be to escape all the HTML-relevant characters in the 3rd party content, and then include it in the ATOM without CDATA
barnabythen it’s just a safe blob of text which is guaranteed to not mess with the surrounding ATOM, and will be parsed to the original content by consumers