Skip to main content
Glama
alexander-zuev

Kollektiv | Your private LLM knowledgebase

consent.ts4.6 kB
import { AppRoutes } from "@/web/routes"; import { base } from "@/web/templates/base"; import type { AuthRequest, ClientInfo } from "@cloudflare/workers-oauth-provider"; import type { User } from "@supabase/supabase-js"; import type { Context } from "hono"; import { html } from "hono/html"; /** * Props needed for rendering the consent screen template. */ export type ConsentScreenProps = { oauthReq: AuthRequest; // Use the central type client?: ClientInfo; // Use the central type user: User; // Use the Supabase User type tx: string; // transaction id csrfToken: string; // from cookie }; export const consentScreen = (props: ConsentScreenProps) => { const clientName = props.client?.clientName || "Application"; const userEmail = props.user?.email; return html` <div class="flex w-full justify-center p-8"> <div class="max-w-lg w-full rounded-lg border border-border bg-card p-6 text-center flex flex-col gap-4 items-center"> <i class="ph ph-handshake text-5xl text-primary mt-4"></i> <h1 class="text-2xl text-center text-foreground">Authorization Request</h1> <p class="text-center text-base text-foreground mb-2"> Authorize <strong>${clientName}</strong> to connect to your Kollektiv <strong> ${userEmail}</strong> account. </p> <div class="w-full text-left space-y-3 my-2"> <p class="text-sm font-medium text-foreground"> <strong>${clientName}</strong> requests read-only access to your Kollektiv account: </p> <div class="flex items-start gap-2 text-sm text-foreground/80"> <i class="ph ph-check-circle text-success text-lg mt-0.5"></i> <span>Search and read the documents you have uploaded</span> </div> </div> <form method="POST" action='${AppRoutes.AUTHORIZE}?tx=${props.tx}' class="w-full"> <input type="hidden" name="csrf" value="${props.csrfToken}"/> <input type="hidden" name="client_id" value="${props.oauthReq.clientId}"/> <input type="hidden" name="state" value="${props.oauthReq.state}"/> <input type="hidden" name="code_challenge" value="${props.oauthReq.codeChallenge}"/> <input type="hidden" name="code_challenge_method" value="${props.oauthReq.codeChallengeMethod}"/> <input type="hidden" name="scope" value="${props.oauthReq.scope}"/> <input type="hidden" name="redirect_uri" value="${props.oauthReq.redirectUri}"/> <!-- Add Approve and Deny buttons --> <div class="flex flex-col sm:flex-row gap-4 mt-4 w-full"> <button type="submit" name="action" value="allow" class="w-full sm:w-1/2 py-3 px-4 bg-primary text-primary-foreground shadow-xs hover:bg-primary-hover rounded-md font-medium transition-colors cursor-pointer" > Allow </button> <button type="submit" name="action" value="deny" class="w-full sm:w-1/2 py-3 px-4 border border-border shadow-xs hover:bg-surface-hover text-foreground transition-colors cursor-pointer" > Deny </button> </div> </form> <div class="flex flex-row items-center gap-2 mt-4 text-sm text-muted-foreground border-t border-border pt-4 w-full justify-start"> <i class="ph ph-shield text-success"></i> <span>Access is limited, revocable, and never includes write permissions.</span> </div> </div> </div> `; }; export async function renderConsentScreen( c: Context, oauthReq: AuthRequest, client: ClientInfo, user: User, tx: string, csrfToken: string, ) { const content = await consentScreen({ oauthReq, client, user, tx, csrfToken }); const pageTitle = `Authorization Request"}`; return c.html(base(content, pageTitle)); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/alexander-zuev/kollektiv-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server