Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -550,13 +550,25 @@ To be released.
[[#912], [#913]]
- Added <https://w3id.org/fep/22cd> to preloaded JSON-LD contexts.
[[#1037], [#1038]]
- Added `toCompatibleEf61Id()` and `fromCompatibleEf61Id()` for converting
between [FEP-ef61] portable IDs and compatible identifiers, which are
HTTP(S) URLs under a gateway's fixed `/.well-known/apgateway/` path that
software without portable IRI support can use. `toCompatibleEf61Id()`
removes location hints (`@gateway` query parameters, and the legacy
`gateways` parameter), and `fromCompatibleEf61Id()` returns
`null` for URLs that are not compatible identifiers and throws a
`TypeError` for malformed ones, including those with location hints.
Converting a compatible identifier does not authenticate it; the object's
proof still has to be verified against its DID. [[#288], [#833], [#1074]]

[#828]: https://github.com/fedify-dev/fedify/issues/828
[#831]: https://github.com/fedify-dev/fedify/issues/831
[#833]: https://github.com/fedify-dev/fedify/issues/833
[#912]: https://github.com/fedify-dev/fedify/issues/912
[#913]: https://github.com/fedify-dev/fedify/pull/913
[#924]: https://github.com/fedify-dev/fedify/pull/924
[#935]: https://github.com/fedify-dev/fedify/pull/935
[#1074]: https://github.com/fedify-dev/fedify/pull/1074

### @fedify/vocab-tools

Expand Down
18 changes: 18 additions & 0 deletions changes.d/vocab-runtime/compatible-ef61-ids.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
links:
'#1074': https://github.com/fedify-dev/fedify/pull/1074
'#288': https://github.com/fedify-dev/fedify/issues/288
'#833': https://github.com/fedify-dev/fedify/issues/833
---
- Added `toCompatibleEf61Id()` and `fromCompatibleEf61Id()` for converting
between [FEP-ef61] portable IDs and compatible identifiers, which are
HTTP(S) URLs under a gateway's fixed `/.well-known/apgateway/` path that
software without portable IRI support can use. `toCompatibleEf61Id()`
removes location hints (`@gateway` query parameters, and the legacy
`gateways` parameter), and `fromCompatibleEf61Id()` returns
`null` for URLs that are not compatible identifiers and throws a
`TypeError` for malformed ones, including those with location hints.
Converting a compatible identifier does not authenticate it; the object's
proof still has to be verified against its DID. [[#288], [#833], [#1074]]

[FEP-ef61]: https://w3id.org/fep/ef61
43 changes: 43 additions & 0 deletions docs/manual/vocab.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,49 @@ const actor = new Person({

Each gateway must be an HTTP(S) base URI with no path, query, or fragment.

Software that does not understand portable IRIs can still refer to portable
objects through *compatible identifiers*: HTTP(S) URLs under a gateway's
fixed `/.well-known/apgateway/` path. Use `toCompatibleEf61Id()` to build
one from a portable ID and a gateway origin, which should be the first item in
the actor's `gateways`, and `fromCompatibleEf61Id()` to get the portable ID
back:

~~~~ typescript twoslash
import {
canonicalizePortableUri,
fromCompatibleEf61Id,
toCompatibleEf61Id,
} from "@fedify/vocab-runtime";

const compatibleId = toCompatibleEf61Id(
"ap+ef61://did:key:z6Mkabc/objects/1",
"https://server1.example",
);
// https://server1.example/.well-known/apgateway/did:key:z6Mkabc/objects/1

const portableId = fromCompatibleEf61Id(compatibleId);
if (portableId != null) {
canonicalizePortableUri(portableId.href);
// ap+ef61://did:key:z6Mkabc/objects/1
}
~~~~

`toCompatibleEf61Id()` removes location hints (`@gateway` query parameters,
and the legacy `gateways` parameter) from the query, because FEP-ef61 forbids
them in compatible identifiers.
`fromCompatibleEf61Id()` returns `null` for URLs that are not compatible
identifiers, and throws a `TypeError` for compatible identifiers that are
malformed or carry location hints. Arbitrary gateway paths are not supported
yet.

> [!WARNING]
>
> A compatible identifier only tells you which portable object it *claims* to
> be. Anyone can serve a compatible identifier for any DID from their own
> server, so the gateway's host is neither the object's origin nor authorized
> to act for the DID. Verify the object's Object Integrity Proof against the
> DID before trusting it.

Links and media/document objects expose `digestMultibase` for the integrity
digest required when portable objects reference external resources. Use
`computeDigestMultibase()` to compute the SHA-256 multihash and
Expand Down
2 changes: 2 additions & 0 deletions packages/vocab-runtime/src/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export {
canonicalizePortableUri,
expandIPv6Address,
formatIri,
fromCompatibleEf61Id,
getFe34Origin,
haveSameFe34Origin,
haveSameIriOrigin,
Expand All @@ -77,6 +78,7 @@ export {
parseGatewayUrl,
parseIri,
parseJsonLdId,
toCompatibleEf61Id,
UrlError,
validatePublicUrl,
} from "./url.ts";
Loading
Loading