diff options
| author | Hazelnoot <acomputerdog@gmail.com> | 2025-05-06 11:20:46 -0400 |
|---|---|---|
| committer | Hazelnoot <acomputerdog@gmail.com> | 2025-05-06 11:20:46 -0400 |
| commit | 95cd19b049804a7a773bdf70b7f72333a38e32be (patch) | |
| tree | 6591dc241c5c04af0bb07a426b21a9f3f4f76108 /packages/backend/src | |
| parent | Merge branch 'develop' into merge/2025-03-24 (diff) | |
| parent | merge: remove http/https protocol in uri on masto api (!980) (diff) | |
| download | sharkey-95cd19b049804a7a773bdf70b7f72333a38e32be.tar.gz sharkey-95cd19b049804a7a773bdf70b7f72333a38e32be.tar.bz2 sharkey-95cd19b049804a7a773bdf70b7f72333a38e32be.zip | |
Merge branch 'develop' into merge/2025-03-24
Diffstat (limited to 'packages/backend/src')
| -rw-r--r-- | packages/backend/src/core/UtilityService.ts | 13 | ||||
| -rw-r--r-- | packages/backend/src/server/ActivityPubServerService.ts | 29 | ||||
| -rw-r--r-- | packages/backend/src/server/api/mastodon/endpoints/instance.ts | 2 |
3 files changed, 38 insertions, 6 deletions
diff --git a/packages/backend/src/core/UtilityService.ts b/packages/backend/src/core/UtilityService.ts index 5209cf7a3d..f8d04c0592 100644 --- a/packages/backend/src/core/UtilityService.ts +++ b/packages/backend/src/core/UtilityService.ts @@ -116,13 +116,22 @@ export class UtilityService { @bindThis public toPuny(host: string): string { - return domainToASCII(host.toLowerCase()); + // domainToASCII will return an empty string if we give it a + // string like `name:123`, but `host` may well be in that form + // (e.g. when testing locally, you'll get `localhost:3000`); split + // the port off, and add it back later + const hostParts = host.toLowerCase().match(/^(.+?)(:.+)?$/); + if (!hostParts) return ''; + const hostname = hostParts[1]; + const port = hostParts[2] ?? ''; + + return domainToASCII(hostname) + port; } @bindThis public toPunyNullable(host: string | null | undefined): string | null { if (host == null) return null; - return domainToASCII(host.toLowerCase()); + return this.toPuny(host); } @bindThis diff --git a/packages/backend/src/server/ActivityPubServerService.ts b/packages/backend/src/server/ActivityPubServerService.ts index 95ee78d660..41beadb56d 100644 --- a/packages/backend/src/server/ActivityPubServerService.ts +++ b/packages/backend/src/server/ActivityPubServerService.ts @@ -179,7 +179,7 @@ export class ActivityPubServerService { this is also inspired by FireFish's `checkFetch` */ - let signature; + let signature: httpSignature.IParsedSignature; try { signature = httpSignature.parseRequest(request.raw, { @@ -232,14 +232,37 @@ export class ActivityPubServerService { return `${logPrefix} signer is suspended: refuse`; } - let httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem); + // some fedi implementations include the query (`?foo=bar`) in the + // signature, some don't, so we have to handle both cases + function verifyWithOrWithoutQuery() { + const httpSignatureValidated = httpSignature.verifySignature(signature, authUser!.key!.keyPem); + if (httpSignatureValidated) return true; + + const requestUrl = new URL(`http://whatever${request.raw.url}`); + if (! requestUrl.search) return false; + + // verification failed, the request URL contained a query, let's try without + const semiRawRequest = request.raw; + semiRawRequest.url = requestUrl.pathname; + + // no need for try/catch, if the original request parsed, this + // one will, too + const signatureWithoutQuery = httpSignature.parseRequest(semiRawRequest, { + headers: ['(request-target)', 'host', 'date'], + authorizationHeaderName: 'signature', + }); + + return httpSignature.verifySignature(signatureWithoutQuery, authUser!.key!.keyPem); + } + + let httpSignatureValidated = verifyWithOrWithoutQuery(); // maybe they changed their key? refetch it // TODO rate-limit this using lastFetchedAt if (!httpSignatureValidated) { authUser.key = await this.apDbResolverService.refetchPublicKeyForApId(authUser.user); if (authUser.key != null) { - httpSignatureValidated = httpSignature.verifySignature(signature, authUser.key.keyPem); + httpSignatureValidated = verifyWithOrWithoutQuery(); } } diff --git a/packages/backend/src/server/api/mastodon/endpoints/instance.ts b/packages/backend/src/server/api/mastodon/endpoints/instance.ts index 0e363446a4..a168339ac6 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/instance.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/instance.ts @@ -39,7 +39,7 @@ export class ApiInstanceMastodon { const instance = data.data; const response: MastodonEntity.Instance = { - uri: this.config.url, + uri: this.config.host, title: this.meta.name || 'Sharkey', description: this.meta.description || 'This is a vanilla Sharkey Instance. It doesn\'t seem to have a description.', email: instance.email || '', |