Loading CHANGES.md +19 −0 Original line number Diff line number Diff line Loading @@ -75,11 +75,30 @@ To be released. - `Service.clone()` method now accepts `service` option. - `Service.clone()` method now accepts `services` option. - The default time window for verifying HTTP Signatures of incoming requests is now an hour (was a minute). This new default window is according to the [ActivityPub and HTTP Signatures] document. - The default value of `VerifyRequestOptions.timeWindow` option became `{ hours: 1 }` (was `{ minutes: 1 }`). - The default value of `CreateFederationOptions.signatureTimeWindow` option became `{ hours: 1 }` (was `{ minutes: 1 }`). - The type of `VerifyRequestOptions.timeWindow` property became `Temporal.Duration | Temporal.DurationLike | false` (was `Temporal.DurationLike | false`). - The type of `CreateFederationOptions.signatureTimeWindow` property became `Temporal.Duration | Temporal.DurationLike | false` (was `Temporal.DurationLike | false`). - In the `fedify inbox` command's web interface, the *Raw Activity* tab is added to show the raw JSON object of the received activity. [FEP-c0e0]: https://w3id.org/fep/c0e0 [FEP-9091]: https://w3id.org/fep/9091 [ActivityPub and HTTP Signatures]: https://swicg.github.io/activitypub-http-signature/ [#146]: https://github.com/dahlia/fedify/issues/146 [#150]: https://github.com/dahlia/fedify/issues/150 Loading src/federation/handler.ts +1 −1 Original line number Diff line number Diff line Loading @@ -356,7 +356,7 @@ export interface InboxHandlerParameters<TContextData> { inboxListeners?: InboxListenerSet<TContextData>; inboxErrorHandler?: InboxErrorHandler<TContextData>; onNotFound(request: Request): Response | Promise<Response>; signatureTimeWindow: Temporal.DurationLike | false; signatureTimeWindow: Temporal.Duration | Temporal.DurationLike | false; skipSignatureVerification: boolean; } Loading src/federation/middleware.ts +5 −5 Original line number Diff line number Diff line Loading @@ -167,13 +167,13 @@ export interface CreateFederationOptions { onOutboxError?: OutboxErrorHandler; /** * The time window for verifying the signature of incoming requests. If the * The time window for verifying HTTP Signatures of incoming requests. If the * request is older or newer than this window, it is rejected. Or if it is * `false`, the request's timestamp is not checked at all. * * By default, the window is a minute. * By default, the window is an hour. */ signatureTimeWindow?: Temporal.DurationLike | false; signatureTimeWindow?: Temporal.Duration | Temporal.DurationLike | false; /** * Whether to skip HTTP Signatures verification for incoming activities. Loading Loading @@ -310,7 +310,7 @@ export class FederationImpl<TContextData> implements Federation<TContextData> { contextLoader: DocumentLoader; authenticatedDocumentLoaderFactory: AuthenticatedDocumentLoaderFactory; onOutboxError?: OutboxErrorHandler; signatureTimeWindow: Temporal.DurationLike | false; signatureTimeWindow: Temporal.Duration | Temporal.DurationLike | false; skipSignatureVerification: boolean; outboxRetryPolicy: RetryPolicy; inboxRetryPolicy: RetryPolicy; Loading Loading @@ -365,7 +365,7 @@ export class FederationImpl<TContextData> implements Federation<TContextData> { ? (identity) => getAuthenticatedDocumentLoader(identity, true) : getAuthenticatedDocumentLoader); this.onOutboxError = options.onOutboxError; this.signatureTimeWindow = options.signatureTimeWindow ?? { minutes: 1 }; this.signatureTimeWindow = options.signatureTimeWindow ?? { hours: 1 }; this.skipSignatureVerification = options.skipSignatureVerification ?? false; this.outboxRetryPolicy = options.outboxRetryPolicy ?? createExponentialBackoffPolicy(); Loading src/sig/http.test.ts +2 −2 Original line number Diff line number Diff line Loading @@ -148,7 +148,7 @@ test("verifyRequest()", async () => { { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader, currentTime: Temporal.Instant.from("2024-03-05T07:48:43.9999Z"), currentTime: Temporal.Instant.from("2024-03-05T06:49:43.9999Z"), }, ), null, Loading @@ -171,7 +171,7 @@ test("verifyRequest()", async () => { { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader, currentTime: Temporal.Instant.from("2024-03-05T07:50:44.0001Z"), currentTime: Temporal.Instant.from("2024-03-05T08:49:44.0001Z"), }, ), null, Loading src/sig/http.ts +4 −3 Original line number Diff line number Diff line Loading @@ -87,9 +87,9 @@ export interface VerifyRequestOptions { * twice the value of this option, with the current time as the center. * Or if it is `false`, no time check is performed. * * A minute by default. * An hour by default. */ timeWindow?: Temporal.DurationLike | false; timeWindow?: Temporal.Duration | Temporal.DurationLike | false; /** * The current time. If not specified, the current time is used. This is Loading Loading @@ -205,7 +205,8 @@ export async function verifyRequest( const date = Temporal.Instant.from(new Date(dateHeader).toISOString()); const now = currentTime ?? Temporal.Now.instant(); if (timeWindow !== false) { const tw: Temporal.DurationLike = timeWindow ?? { minutes: 1 }; const tw: Temporal.Duration | Temporal.DurationLike = timeWindow ?? { hours: 1 }; if (Temporal.Instant.compare(date, now.add(tw)) > 0) { logger.debug( "Failed to verify; Date is too far in the future.", Loading Loading
CHANGES.md +19 −0 Original line number Diff line number Diff line Loading @@ -75,11 +75,30 @@ To be released. - `Service.clone()` method now accepts `service` option. - `Service.clone()` method now accepts `services` option. - The default time window for verifying HTTP Signatures of incoming requests is now an hour (was a minute). This new default window is according to the [ActivityPub and HTTP Signatures] document. - The default value of `VerifyRequestOptions.timeWindow` option became `{ hours: 1 }` (was `{ minutes: 1 }`). - The default value of `CreateFederationOptions.signatureTimeWindow` option became `{ hours: 1 }` (was `{ minutes: 1 }`). - The type of `VerifyRequestOptions.timeWindow` property became `Temporal.Duration | Temporal.DurationLike | false` (was `Temporal.DurationLike | false`). - The type of `CreateFederationOptions.signatureTimeWindow` property became `Temporal.Duration | Temporal.DurationLike | false` (was `Temporal.DurationLike | false`). - In the `fedify inbox` command's web interface, the *Raw Activity* tab is added to show the raw JSON object of the received activity. [FEP-c0e0]: https://w3id.org/fep/c0e0 [FEP-9091]: https://w3id.org/fep/9091 [ActivityPub and HTTP Signatures]: https://swicg.github.io/activitypub-http-signature/ [#146]: https://github.com/dahlia/fedify/issues/146 [#150]: https://github.com/dahlia/fedify/issues/150 Loading
src/federation/handler.ts +1 −1 Original line number Diff line number Diff line Loading @@ -356,7 +356,7 @@ export interface InboxHandlerParameters<TContextData> { inboxListeners?: InboxListenerSet<TContextData>; inboxErrorHandler?: InboxErrorHandler<TContextData>; onNotFound(request: Request): Response | Promise<Response>; signatureTimeWindow: Temporal.DurationLike | false; signatureTimeWindow: Temporal.Duration | Temporal.DurationLike | false; skipSignatureVerification: boolean; } Loading
src/federation/middleware.ts +5 −5 Original line number Diff line number Diff line Loading @@ -167,13 +167,13 @@ export interface CreateFederationOptions { onOutboxError?: OutboxErrorHandler; /** * The time window for verifying the signature of incoming requests. If the * The time window for verifying HTTP Signatures of incoming requests. If the * request is older or newer than this window, it is rejected. Or if it is * `false`, the request's timestamp is not checked at all. * * By default, the window is a minute. * By default, the window is an hour. */ signatureTimeWindow?: Temporal.DurationLike | false; signatureTimeWindow?: Temporal.Duration | Temporal.DurationLike | false; /** * Whether to skip HTTP Signatures verification for incoming activities. Loading Loading @@ -310,7 +310,7 @@ export class FederationImpl<TContextData> implements Federation<TContextData> { contextLoader: DocumentLoader; authenticatedDocumentLoaderFactory: AuthenticatedDocumentLoaderFactory; onOutboxError?: OutboxErrorHandler; signatureTimeWindow: Temporal.DurationLike | false; signatureTimeWindow: Temporal.Duration | Temporal.DurationLike | false; skipSignatureVerification: boolean; outboxRetryPolicy: RetryPolicy; inboxRetryPolicy: RetryPolicy; Loading Loading @@ -365,7 +365,7 @@ export class FederationImpl<TContextData> implements Federation<TContextData> { ? (identity) => getAuthenticatedDocumentLoader(identity, true) : getAuthenticatedDocumentLoader); this.onOutboxError = options.onOutboxError; this.signatureTimeWindow = options.signatureTimeWindow ?? { minutes: 1 }; this.signatureTimeWindow = options.signatureTimeWindow ?? { hours: 1 }; this.skipSignatureVerification = options.skipSignatureVerification ?? false; this.outboxRetryPolicy = options.outboxRetryPolicy ?? createExponentialBackoffPolicy(); Loading
src/sig/http.test.ts +2 −2 Original line number Diff line number Diff line Loading @@ -148,7 +148,7 @@ test("verifyRequest()", async () => { { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader, currentTime: Temporal.Instant.from("2024-03-05T07:48:43.9999Z"), currentTime: Temporal.Instant.from("2024-03-05T06:49:43.9999Z"), }, ), null, Loading @@ -171,7 +171,7 @@ test("verifyRequest()", async () => { { documentLoader: mockDocumentLoader, contextLoader: mockDocumentLoader, currentTime: Temporal.Instant.from("2024-03-05T07:50:44.0001Z"), currentTime: Temporal.Instant.from("2024-03-05T08:49:44.0001Z"), }, ), null, Loading
src/sig/http.ts +4 −3 Original line number Diff line number Diff line Loading @@ -87,9 +87,9 @@ export interface VerifyRequestOptions { * twice the value of this option, with the current time as the center. * Or if it is `false`, no time check is performed. * * A minute by default. * An hour by default. */ timeWindow?: Temporal.DurationLike | false; timeWindow?: Temporal.Duration | Temporal.DurationLike | false; /** * The current time. If not specified, the current time is used. This is Loading Loading @@ -205,7 +205,8 @@ export async function verifyRequest( const date = Temporal.Instant.from(new Date(dateHeader).toISOString()); const now = currentTime ?? Temporal.Now.instant(); if (timeWindow !== false) { const tw: Temporal.DurationLike = timeWindow ?? { minutes: 1 }; const tw: Temporal.Duration | Temporal.DurationLike = timeWindow ?? { hours: 1 }; if (Temporal.Instant.compare(date, now.add(tw)) > 0) { logger.debug( "Failed to verify; Date is too far in the future.", Loading