Files
zeekay be1d26a502 Let a recipient without an account sign
The socket the app's pages call over (/zap) opened only for a session, so
a recipient signing by their link, who has no account, could not reach
the routes that sign a field or complete a document: every field they
clicked failed with "An error occurred while signing the field". tRPC had
served those as public procedures; the port to ZAP kept their bodies and
lost the door.

A connection from the app's own pages with no session now opens as
anonymous and reaches only the routes tRPC served publicly, each
authorised by the token it carries; every other route answers it 401
before its handler runs. The operation API still refuses a request
without a token.
2026-10-20 12:41:58 -07:00

57 lines
2.1 KiB
TypeScript

// esign ZAP RPC — the route registry.
//
// The single map of fully-ported routes the dispatcher serves. Each entry is
// "<router>.<procedure>" → handler. Any route absent here resolves to a
// NOT_FOUND reply (see dispatch.ts).
//
// All 14 tRPC routers are ported to ZAP handlers:
// admin, apiToken, auth, document, embeddingPresign, envelope, field,
// folder, organisation, profile, recipient, team, template, webhook.
import type { ZapRouteMap } from './dispatch';
import { adminRoutes } from './handlers/admin';
import { apiTokenRoutes } from './handlers/api-token';
import { authRoutes } from './handlers/auth';
import { documentRoutes } from './handlers/document';
import { embeddingRoutes } from './handlers/embedding';
import { envelopeRoutes } from './handlers/envelope';
import { fieldRoutes } from './handlers/field';
import { folderRoutes } from './handlers/folder';
import { organisationRoutes } from './handlers/organisation';
import { profileRoutes } from './handlers/profile';
import { recipientRoutes } from './handlers/recipient';
import { teamRoutes } from './handlers/team';
import { templateRoutes } from './handlers/template';
import { webhookRoutes } from './handlers/webhook';
import { publicRoutes } from './public-routes';
export const zapRoutes: ZapRouteMap = {
...adminRoutes,
...apiTokenRoutes,
...authRoutes,
...documentRoutes,
...embeddingRoutes,
...envelopeRoutes,
...fieldRoutes,
...folderRoutes,
...organisationRoutes,
...profileRoutes,
...recipientRoutes,
...teamRoutes,
...templateRoutes,
...webhookRoutes,
};
export { publicRoutes };
// A public route the server does not serve is a typo that would refuse a
// recipient in production; it stops the server at boot instead.
for (const route of publicRoutes) {
if (!(route in zapRoutes)) {
throw new Error(`publicRoutes names ${route}, which no handler serves`);
}
}
/** The set of routes the ZAP server can handle (used by the client to decide
* whether to dispatch over ZAP or fall back to the legacy tRPC client). */
export const migratedRoutes: ReadonlySet<string> = new Set(Object.keys(zapRoutes));