aboutsummaryrefslogtreecommitdiff
path: root/src/activity/index.ts
diff options
context:
space:
mode:
authorElizabeth Hunt <me@liz.coffee>2025-12-15 00:58:43 -0800
committerElizabeth Hunt <me@liz.coffee>2025-12-15 00:58:43 -0800
commit2e41f030f02a336c2e9866d3d56b0494da5a622e (patch)
tree226d7fe0f2e0d5af847c31d97c1ab9664d1b7e33 /src/activity/index.ts
parent9c9f35734e795e3c2cea21384349b655d7ffa164 (diff)
downloadposthook-2e41f030f02a336c2e9866d3d56b0494da5a622e.tar.gz
posthook-2e41f030f02a336c2e9866d3d56b0494da5a622e.zip
Remove admin route in favor of a simpler toml format
Diffstat (limited to 'src/activity/index.ts')
-rw-r--r--src/activity/index.ts123
1 files changed, 1 insertions, 122 deletions
diff --git a/src/activity/index.ts b/src/activity/index.ts
index e14507d..d3537b4 100644
--- a/src/activity/index.ts
+++ b/src/activity/index.ts
@@ -4,7 +4,6 @@ import {
type IActivity,
type IEither,
type ITraceable,
- jsonModel,
JsonResponse,
LogLevel,
LogMetricTraceSupplier,
@@ -16,83 +15,14 @@ import {
TraceUtil,
} from '@emprespresso/pengueno';
import type { Storage } from '../storage/index.js';
-import type { RouteConfig } from '../types/index.js';
-import { isRouteConfig, ContentType } from '../types/index.js';
+import { ContentType } from '../types/index.js';
import { verifyHCaptcha } from '../integrations/hcaptcha.js';
import { sendNtfyNotification } from '../integrations/ntfy.js';
import { TokenSigner } from '../token/index.js';
-const routeConfigMetric = Metric.fromName('Route.Config').asResult();
const webhookRequestMetric = Metric.fromName('Webhook.Process').asResult();
-const listRoutesMetric = Metric.fromName('Routes.List').asResult();
const tokenGenerateMetric = Metric.fromName('Token.Generate').asResult();
-export interface IRegisterRouteActivity {
- registerRoute: IActivity;
-}
-
-export class RegisterRouteActivityImpl implements IRegisterRouteActivity {
- constructor(private readonly storage: Storage) {}
-
- private trace(r: ITraceable<PenguenoRequest, ServerTrace>) {
- return r.flatMap(TraceUtil.withClassTrace(this)).flatMap(TraceUtil.withMetricTrace(routeConfigMetric));
- }
-
- public registerRoute(r: ITraceable<PenguenoRequest, ServerTrace>) {
- const routeConfigTransformer = (j: ITraceable<unknown, ServerTrace>): IEither<PenguenoError, RouteConfig> => {
- const config = j.get();
- if (!isRouteConfig(config)) {
- const err = 'Invalid route configuration';
- j.trace.traceScope(LogLevel.WARN).trace(err);
- return Either.left(new PenguenoError(err, 400));
- }
- return Either.right(config);
- };
-
- return this.trace(r)
- .map(jsonModel(routeConfigTransformer))
- .map(async (tEitherConfig) => {
- const eitherConfig = await tEitherConfig.get();
- return eitherConfig.flatMapAsync(async (config) => {
- const eitherStored = await this.storage.registerRoute(config);
- return eitherStored.mapLeft((e) => new PenguenoError(e.message, 500));
- });
- })
- .flatMapAsync(
- TraceUtil.promiseify((tEitherStored) => {
- const errorSource = tEitherStored
- .get()
- .left()
- .map(({ source }) => source)
- .orSome(() => ErrorSource.SYSTEM)
- .get();
- const shouldWarn = errorSource === ErrorSource.USER;
- return TraceUtil.traceResultingEither<PenguenoError, void, LogMetricTraceSupplier>(
- routeConfigMetric,
- shouldWarn,
- )(tEitherStored);
- }),
- )
- .peek(
- TraceUtil.promiseify((tResult) =>
- tResult.get().mapRight(() => tResult.trace.trace('Route registered successfully')),
- ),
- )
- .map(
- TraceUtil.promiseify((tEitherResult) => {
- const result = tEitherResult.get().mapRight(() => ({ success: true }));
- return new JsonResponse(r, result, {
- status: result.fold(
- ({ status }) => status,
- () => 200,
- ),
- });
- }),
- )
- .get();
- }
-}
-
export interface IWebhookActivity {
processWebhook: (routeName: string) => IActivity;
}
@@ -443,57 +373,6 @@ export class WebhookActivityImpl implements IWebhookActivity {
}
}
-export interface IListRoutesActivity {
- listRoutes: IActivity;
-}
-
-export class ListRoutesActivityImpl implements IListRoutesActivity {
- constructor(private readonly storage: Storage) {}
-
- private trace(r: ITraceable<PenguenoRequest, ServerTrace>) {
- return r.flatMap(TraceUtil.withClassTrace(this)).flatMap(TraceUtil.withMetricTrace(listRoutesMetric));
- }
-
- public listRoutes(r: ITraceable<PenguenoRequest, ServerTrace>) {
- type ListRoutesResult = {
- routes: Array<{
- name: string;
- contentType: ContentType;
- hcaptchaProtected: boolean;
- ntfyEnabled: boolean;
- requireToken: boolean;
- }>;
- };
-
- return this.trace(r)
- .map((tReq) => {
- void tReq.get();
-
- const routes = this.storage.listRoutes();
- const sanitized = routes.map(({ name, contentType, hcaptchaProtected, ntfy, requireToken }) => ({
- name,
- contentType,
- hcaptchaProtected,
- ntfyEnabled: ntfy?.enabled || false,
- requireToken: requireToken || false,
- }));
- return Either.right<PenguenoError, ListRoutesResult>({ routes: sanitized });
- })
- .peek(
- TraceUtil.traceResultingEither<PenguenoError, ListRoutesResult, LogMetricTraceSupplier>(
- listRoutesMetric,
- ),
- )
- .map(
- async (tEitherResult) =>
- new JsonResponse(r, tEitherResult.get(), {
- status: 200,
- }),
- )
- .get();
- }
-}
-
export interface ITokenGenerateActivity {
generateToken: (routeName: string) => IActivity;
}