rswag-online/frontend/vendor/@encryptid/sdk/server/middleware/nextjs.d.ts

137 lines
5.2 KiB
TypeScript

/**
* EncryptID Next.js Middleware
*
* Helpers for protecting Next.js App Router routes and API endpoints.
*/
import { type VerifyOptions } from '../jwt-verify.js';
import { type SpaceAuthOptions } from '../space-auth.js';
import type { EncryptIDClaims, SpaceAuthResult, SpaceVisibility } from '../../types/index.js';
import type { ResolvedRole, SpaceMembership } from '../../types/roles.js';
export interface EncryptIDNextConfig extends VerifyOptions {
/** Paths that don't require authentication */
publicPaths?: string[];
/** Redirect URL for unauthenticated requests (null = return 401) */
loginUrl?: string | null;
}
/**
* Get EncryptID session from a Next.js request
*
* Usage in API routes:
* ```ts
* import { getEncryptIDSession } from '@encryptid/sdk/server/nextjs';
*
* export async function GET(req: Request) {
* const session = await getEncryptIDSession(req);
* if (!session) return new Response('Unauthorized', { status: 401 });
* // session.sub, session.did, session.eid.authLevel, etc.
* }
* ```
*/
export declare function getEncryptIDSession(request: Request, options?: VerifyOptions): Promise<EncryptIDClaims | null>;
/**
* Protect a Next.js API route handler
*
* Usage:
* ```ts
* import { withEncryptID } from '@encryptid/sdk/server/nextjs';
*
* export const GET = withEncryptID(async (req, session) => {
* return Response.json({ user: session.sub, did: session.did });
* });
* ```
*/
export declare function withEncryptID(handler: (request: Request, session: EncryptIDClaims) => Promise<Response>, options?: VerifyOptions): (request: Request) => Promise<Response>;
/**
* Create Next.js middleware for EncryptID
*
* Usage in middleware.ts:
* ```ts
* import { createEncryptIDMiddleware } from '@encryptid/sdk/server/nextjs';
*
* const encryptIDMiddleware = createEncryptIDMiddleware({
* publicPaths: ['/auth/signin', '/api/auth'],
* loginUrl: '/auth/signin',
* });
*
* export function middleware(request: NextRequest) {
* return encryptIDMiddleware(request);
* }
* ```
*/
export declare function createEncryptIDMiddleware(config?: EncryptIDNextConfig): (request: Request) => Promise<Response | null>;
/**
* Check space access in a Next.js API route or server component.
*
* Usage:
* ```ts
* const result = await checkSpaceAccess(request, spaceSlug, {
* getSpaceConfig: async (slug) => {
* const space = await prisma.space.findUnique({ where: { slug } });
* if (!space) return null;
* return { spaceSlug: slug, visibility: space.visibility, app: 'rvote' };
* },
* });
* if (!result.allowed) return new Response(result.reason, { status: 401 });
* ```
*/
export declare function checkSpaceAccess(request: Request, spaceSlug: string, options: SpaceAuthOptions): Promise<SpaceAuthResult>;
/**
* HOC that wraps a Next.js API route handler with space auth.
*
* Usage:
* ```ts
* export const POST = withSpaceAuth(
* async (req, spaceAuth, slug) => {
* return Response.json({ owner: spaceAuth.isOwner });
* },
* (req) => new URL(req.url).pathname.split('/')[2],
* { getSpaceConfig: async (slug) => { ... } },
* );
* ```
*/
export declare function withSpaceAuth(handler: (request: Request, spaceAuth: SpaceAuthResult, spaceSlug: string) => Promise<Response>, getSlug: (request: Request) => string, options: SpaceAuthOptions): (request: Request) => Promise<Response>;
export interface SpaceRoleOptions extends SpaceAuthOptions {
/** Look up membership for a DID in a space. You provide the DB query. */
getMembership: (userDID: string, spaceSlug: string) => Promise<SpaceMembership | null>;
/** Resolve visibility for a space slug. If not provided, uses getSpaceConfig. */
getVisibility?: (spaceSlug: string) => Promise<SpaceVisibility>;
}
export interface SpaceRoleResult {
spaceAuth: SpaceAuthResult;
resolvedRole: ResolvedRole;
}
/**
* Check space access AND resolve role in one call.
*
* Usage:
* ```ts
* const result = await checkSpaceRole(request, slug, {
* getSpaceConfig: async (slug) => prisma.space.findUnique({ where: { slug } }),
* getMembership: async (did, slug) => prisma.spaceMember.findUnique({
* where: { userDID_spaceSlug: { userDID: did, spaceSlug: slug } }
* }),
* });
* if (!result.spaceAuth.allowed) return deny();
* if (hasCapability(result.resolvedRole.role, 'create_proposal', RVOTE_PERMISSIONS)) { ... }
* ```
*/
export declare function checkSpaceRole(request: Request, spaceSlug: string, options: SpaceRoleOptions): Promise<SpaceRoleResult>;
/**
* HOC that wraps a Next.js API route handler with space auth + role resolution.
*
* Usage:
* ```ts
* export const POST = withSpaceRole(
* async (req, spaceAuth, role, slug) => {
* if (!hasCapability(role.role, 'create_proposal', RVOTE_PERMISSIONS)) {
* return Response.json({ error: 'Forbidden' }, { status: 403 });
* }
* return Response.json({ created: true });
* },
* (req) => new URL(req.url).pathname.split('/')[3], // extract slug
* { getSpaceConfig: ..., getMembership: ... },
* );
* ```
*/
export declare function withSpaceRole(handler: (request: Request, spaceAuth: SpaceAuthResult, resolvedRole: ResolvedRole, spaceSlug: string) => Promise<Response>, getSlug: (request: Request) => string, options: SpaceRoleOptions): (request: Request) => Promise<Response>;