Overview
I wish to introduce a new mechanic for matching claims to service providers. With my proposal, service providers are able specify so-called markers which are used as additional tests before attempting to verify a claim. For now, markers are only HTTP endpoints and can only be tested for their existence — or lack of.
Rationale
Currently, when an identity claim is parsed, it is matched to candidate service providers before attempting to verify the claim. This matching is done solely based on the URI of the claim.
Some service providers are not ambiguous: IRC claims always start with irc:, lichess claims will always use the lichess.org domain.
Most service providers are ambiguous: https://domain.org/username/post could refer to a forem account, a forgejo/gitea account, an owncast instance...
Currently, doip-js simply attempts each of these service providers until one is able to verify the claim.
This worked fine until gitea was forked and forgejo was created. Due to their identical roots, both gitea and forgejo use the same verification mechanism and are thus indistinguishable from doip-js point of view. Other projects and their forks will experience a similar issue.
Markers are one way of solving this issue. This proposal would add a marker to the forgejo service provider that the gitea service provider does not have: the /api/forgejo/v1/version HTTP endpoint.
Note: for this to work, it is important that forgejo gets attempted BEFORE gitea, since gitea does not have a marker that forgejo does not have. doip-js does this.
Execution
This proposal would see the markers property being added to all service provider configs. An example would look as such:
{
...
markers: [
{
request: {
fetcher: E.Fetcher.HTTP,
access: E.ProofAccess.NOCORS,
format: E.ProofFormat.JSON,
data: {
url: `https://${match[1]}/api/forgejo/v1/version`,
format: E.ProofFormat.JSON
}
},
test: {
type: E.MarkerTestType.HTTP_ENDPOINT_MUST_EXIST,
inverse: false
}
}
],
...
}
A marker is an object with two properties: request and test.
The request property follows the same rules as the proof.request property so that we can use the same "direct/proxy" HTTP request logic.
The test property will explain how to test the requested resource. In this proposal, test has two properties: type (a predefined list of tests) and inverse (whether the expected result should be positive or negative).
Example test types could be:
HTTP_ENDPOINT_MUST_EXIST: if HTTP status < 400, consider this test validatedJSON_MUST_CONTAIN: if a specified property of the resulting JSON body contains a specified value, consider this test validated
Example
Thanks to markers, doip-js will be perfectly able to handle the following two scenarios.
Scenario 1: a forgejo claim is asked to be verified. It gets matched to both forgejo and gitea. Forgejo is attempted. doip-js finds that the /api/forgejo/v1/version endpoint exists and continues. It attempts the actual verification which succeeds. This claim is now a verified forgejo account.
Scenario 2: a gitea claim is asked to be verified. It gets matched to both forgejo and gitea. Forgejo is attempted. doip-js finds that the /api/forgejo/v1/version endpoint does not exist and skips forgejo. Gitea is attempted. It attempts the actual verification which succeeds. This claim is now a verified gitea account.
Note: in scenario 1, the gitea service provider is never even attempted, preventing this gitea verification — which would succeed! — to "confuse" doip-js.
Todo
- Improve this issue (more examples, explain better the various mandatory and optional properties)