# dwebFinger
🤙
## tl;dr
Webfinger's spec forbids what many want, which are online names like `@bengo.is` and `@company.com/store/product` not only (as webfinger requires) `@username@serviceProvider.com`. This fixes that. You can just hand out your 'handle' is `@bengo.is` and if anyone ever yells at you for not conforming to their preferred specification you can just say you prefer this one.
## Abstract
dwebFinger is a variant of webfinger that composes well with modern media types and disregards the antiquated application/jrd+json required by [RFC7033][]
It composes much better with JSON-LD-based protocols like DID, ActivityPub, and [EIP-4824](https://eips.ethereum.org/EIPS/eip-4824) which use media type `application/ld+json` and otherwise never require developers to deal with `application/jrd`.
## How it Works
* like webfinger, it resolves URIs like `acct:<user-part>@<domain-art>`
* unlike webfinger, it doesn't require dealing with any XRD or JRD media types, which are unnecessary when using RDF as a data model like in ActivityStreams2, ActivityPub, and DID.
* the `<user-part>` before the `@` is now optional, as it is not required for users who are hosting their own names
* `acct:` URIs may have a path component.
## Difference from Webfinger-RFC7033
### Accept header required in requests
In Webfinger-RFC7033, the resolving client makes an HTTP request with no `Accept` header to indicate the media types it can handle. The server always responds with a `Content-Type: application/jrd+json`
In dwebfinger, the resolving client MUST send an `Accept` header indicating media types that it expects.
Clients MAY include `application/ld+json; profile="https://www.w3.org/ns/activitystreams"` in this request.
When `application/ld+json; profile="https://www.w3.org/ns/activitystreams"` is in the Accept header, a valid response to a webfinger request is an [ActivityStreams 2.0 Profile](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-profile), i.e. an ActivityPub Actor Object.
In this way, a dwebfinger client request MAY also be a valid ActivityPub Object request.
Clients MAY include `application/ld+json` in this request.
When `application/ld+json` is in the Accept header, a [DID Document](https://www.w3.org/TR/did-core/#example-a-simple-did-document) is an example of a valid response. So is a JSON object that meets the syntactic requirements of both ActivityStreams 2.0 Profiles and DID Document JSON objects.
dwebfinger servers MAY identify a dwebfinger request by the presence of the `Accept` header.
### `user-part` not required in `acct:` URI
Webfinger-[RFC7033][] defines `acct:` uri syntax and requires a `user-part` that is at least a quoted string like `""@example.com`.
dwebfinger extends the `acct:` URI syntax to allow an empty string as the `user-part`.
`acct:@bengo.is` is now a valid dwebfinger URI. It resolves to https://bengo.is/.well-known/webfinger?resource=@bengo.is
### path-based fallback
In Webfinger-RFC7033, all name resolution goes through a well-known URI (usually) with centralized control by the domain operator.
In dwebfinger, if the `/.well-known` URI for the webfinger account cannot be found, and the `acct:` URI does not have a `user-part`, clients SHOULD make the same request to the URI that is the result of replacing `acct:@` in the acct URI with `https://`.
For example, a client resolving `acct:@bengo.is` may resolve this identifier by making a request to `https://bengo.is` (with an `Accept` header).
A client resolving `acct:@bengo.is/persona` may resolve this identifier by making an http request to `https://bengo.is/persona`.
This has the benefit of making webfinger useful for web users who only control a URI-prefixed namespace like the URIs with prefix `https://pages.example.com/bengo/`.
If you can publish a document at a URI, you can use it as a dwebfinger handle.
### hashlinks
dwebfinger `acct:` URIs MAY have a fragment identifier.
It MAY be a [hashlink](https://datatracker.ietf.org/doc/html/draft-sporny-hashlink-07) and the hashlink MAY indicate supported media types that can be served the webfinger server.
### path-only is allowed
`acct:/` is allowed and has an empty `user-part`, empty `domain-part` and a `path` of `/`. This is allowed, but the uri authority is undefined, and may be determined by other means.
Implementations MAY translate strings like `@/` into URIs like `acct:/` and resolve the `acct:` URI from there.
`@/ipfs/{cid}` corresponds to (syntactically) `acct:/ipfs/{cid}`
`@/dns4/bengo.is/http/GET/actor.json` corresponds to `acct:/dns4/bengo.is/http/GET/actor.json`
## dwebfinger RFC7033 Compatability Mode
dwebfinger clients MAY indicate support for Webfinger-RFC7033 responses by including an Accept header value of `application/jrd+json` (possibly alongside other acceptable media types as well). Webfinger-RFC7033 servers that are not aware of dwebfinger will still respond in a way interpretable by dwebfinger clients because they will respond with `Content-Type: application/jrd+json`. dwebfinger clients supporting RFC7033 Compatability Mode must accept `application/jrd+json` response types, but this is not required for dwebfinger conformance in general.
[RFC7033]: https://www.rfc-editor.org/rfc/rfc7033.html
## Other Compatability Modes
Other compatability modes are encouraged in community specifications. What are other reasonable ways to resolve @domain.com/store/product?
For example, when resources allow, or nothing else works, clients could resolve `domain.com` via DNS lookups as is common in Jabber, [DID](https://www.ietf.org/archive/id/draft-carter-high-assurance-dids-with-dns-07.html), and ATProto fediverse communities, and resolve any path component (e.g. `/store/product` according to whichever resolution scheme the domain supports). dwebFinger is primarily an adapter to WebFinger, for those who insist on using it despite its limitations and SocialWG Consensus to omit it from ActivityPub.
## Examples
dwebfinger request using `curl` and only using the media type `application/json` with no one required to implement JRD/XRD.
```shell
âš¡ curl 'https://bengo.is/.well-known/webfinger?resource=acct:bengo.is' \
-H "Accept: application/json"
{
"subject": "acct:\"\"@bengo.is",
"aliases": [
"https://bengo.is",
"did:web:bengo.is",
"https://mastodon.social/@bengo"
],
"links": [
{
"type": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
"href": "https://bengo.is/actor.json"
},
{
"rel": "http://webfinger.net/rel/profile-page",
"type": "text/html",
"href": "https://bengo.is"
}
]
}
```
```shell
âš¡ curl 'https://bengo.is/.well-known/webfinger?resource=acct:did:web:bengo.is' \
-H "Accept: application/json"
{
"subject": "acct:did:web:bengo.is",
"aliases": [
"https://bengo.is",
"did:web:bengo.is",
"https://mastodon.social/@bengo"
],
"links": [
{
"type": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
"href": "https://bengo.is/actor.json"
},
{
"rel": "http://webfinger.net/rel/profile-page",
"type": "text/html",
"href": "https://bengo.is"
}
]
}
```
## License
https://creativecommons.org/licenses/by-sa/4.0/