1import * as machines from "@distilled.cloud/fly-io/machines";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as FetchHttpClient from "effect/http/FetchHttpClient";
5import { CredentialsFromAmbientOrEnv } from "./Credentials.ts";
6import { bytesToBase64, makeHttpSecretKeyBinding } from "./SecretKeyHttp.ts";
7import { Verify, type VerifyRequest } from "./Verify.ts";
8
9/**
10 * HTTP implementation of {@link Verify}. Provide it on the
11 * {@link Service} or Action Effect.
12 *
13 *
14 * ### Provide the layer
15 * **Example:** On a Service
16 * ```typescript
17 * Effect.gen(function* () {
18 * const verify = yield* Fly.Verify(Signing);
19 * // ...
20 * }).pipe(Effect.provide(Fly.VerifyHttp))
21 * ```
22 *
23 * @layer
24 * @product Secret Key
25 * @provides Fly.Verify
26 */
27export const VerifyHttp = Layer.effect(
28 Verify,
29 Effect.suspend(() =>
30 makeHttpSecretKeyBinding({
31 makeClient: (auth, appName, secretName) =>
32 Effect.fn("Fly.Verify")(function* (request: VerifyRequest) {
33 // Fly answers 200 only when the signature checks out.
34 yield* auth.authorize(
35 machines.verifySecretKey({
36 app_name: yield* appName,
37 secret_name: yield* secretName,
38 plaintext: bytesToBase64(request.plaintext),
39 signature: bytesToBase64(request.signature),
40 }),
41 );
42 return { valid: true as const };
43 }),
44 }),
45 ),
46).pipe(
47 Layer.provide(FetchHttpClient.layer),
48 Layer.provide(CredentialsFromAmbientOrEnv),
49);