1.0.0 • Published 3 months ago

fedi-get-key v1.0.0

Weekly downloads
-
License
ISC
Repository
gitlab
Last release
3 months ago

fedi-get-key

A library for fetching the public key from an activitypub actor, for use in fediverse applications. You can use this library to obtain a key for verifying an HTTP signature header, for example.

Note that you need to know the key ID URI in order to use this library - just knowing the actor's URI is not enough.

The document containing the key must use the sec:owner and sec:publicKeyPem terms from the WC3 Security Draft vocabulary. The document containing the key's owner must use the sec:publicKey term.

import KeyFetcher from 'fedi-get-key';

// Bring your own fetch implementation (the global fetch is fine)
const keyFetcher = new KeyFetcher(globalThis.fetch);

const keyUri = 'https://example.com/users/Paul#main-key';

const result = await keyFetcher.get(keyUri);

// This is the public key for the given URI
console.log(result.key); // "-----BEGIN PUBLIC KEY-----\n...etc...\n-----END PUBLIC KEY-----\n"

// This is the parsed JSON-LD document representing the key's owner
console.log(result.owner); // { @context: { etc }, id: 'https://example.com/users/Paul', preferredUsername: 'Paul', /* ...etc... */  }

Ownership

As well as fetching the key, this library will check that there's a two-way relationship between the key and its owner; the key must have a sec:owner property that points to an actor, and that actor must have a sec:publicKey property that points to the key.

These objects may be in the same document or in different documents - if the actor is in a separate document to the key, a second fetch request will be made to resolve the actor.

Fetch implementation

The KeyFetcher constructor accepts a fetch-like function as its argument. This function doesn't need to implement the full fetch specification, just certain parts; namely, it must accept a string url argument and options object of the form { headers: { accept: string } }, and return a response object with the ok and json properties and a headers collection with a get function.

The typescript definitions are as follows:

type FetchLite = (url: string, options: FetchLiteOptions) => Promise<FetchLiteResponse>;

type FetchLiteOptions = {
    headers: {
        accept: string
    }
}

type FetchLiteResponse = {
    ok: boolean,
    headers: {
        get(name: string): string | null
    },
    json(): Promise<unknown>
}

While you can use the global fetch, you may wish to create a wrapper function which—for example—enforces HTTPS, aborts the request after a timeout, or caches responses.