| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- /**
- * Briven Auth M2M (machine-to-machine) — server only.
- * SuperTokens-style client_credentials via briven-engine.
- * @see https://supertokens.com/docs/authentication/m2m/client-credentials
- * @see Briven docs/HANDOFF-AUTH-M2M-FOR-ALL-PROJECTS.md
- *
- * Never import this from client components. Never put m2ms_ secrets in NEXT_PUBLIC_*.
- */
- type M2mTokenCache = { accessToken: string; expiresAtMs: number };
- let cache: M2mTokenCache | null = null;
- function apiOrigin(): string {
- return (
- process.env.BRIVEN_API_ORIGIN?.trim() ||
- process.env.NEXT_PUBLIC_BRIVEN_API_ORIGIN?.trim() ||
- "https://api.briven.tech"
- );
- }
- export function isM2mConfigured(): boolean {
- const id = process.env.BRIVEN_M2M_CLIENT_ID?.trim() ?? "";
- const secret = process.env.BRIVEN_M2M_CLIENT_SECRET?.trim() ?? "";
- return id.startsWith("m2m_") && secret.startsWith("m2ms_");
- }
- /**
- * Mint (or reuse cached) M2M access token.
- * Token TTL is ~3600s; refresh 60s early.
- */
- export async function getBrivenM2mToken(): Promise<string> {
- if (!isM2mConfigured()) {
- throw new Error(
- "M2M not configured. Create a machine client in Briven Auth → Keys, then set BRIVEN_M2M_CLIENT_ID + BRIVEN_M2M_CLIENT_SECRET.",
- );
- }
- const now = Date.now();
- if (cache && cache.expiresAtMs > now + 60_000) {
- return cache.accessToken;
- }
- const res = await fetch(`${apiOrigin()}/v1/auth-core/oauth/token`, {
- method: "POST",
- headers: { "content-type": "application/json" },
- body: JSON.stringify({
- grant_type: "client_credentials",
- client_id: process.env.BRIVEN_M2M_CLIENT_ID,
- client_secret: process.env.BRIVEN_M2M_CLIENT_SECRET,
- }),
- cache: "no-store",
- });
- if (!res.ok) {
- const text = await res.text();
- throw new Error(`m2m token failed: ${res.status} ${text.slice(0, 200)}`);
- }
- const data = (await res.json()) as {
- access_token: string;
- expires_in: number;
- project_id?: string;
- role?: string;
- };
- cache = {
- accessToken: data.access_token,
- expiresAtMs: now + (data.expires_in ?? 3600) * 1000,
- };
- return cache.accessToken;
- }
- /** Example: call project info with M2M bearer. */
- export async function brivenProjectInfoWithM2m(): Promise<unknown> {
- const token = await getBrivenM2mToken();
- const projectId =
- process.env.BRIVEN_PROJECT_ID?.trim() ||
- process.env.NEXT_PUBLIC_BRIVEN_PROJECT_ID?.trim();
- if (!projectId) throw new Error("BRIVEN_PROJECT_ID missing");
- const res = await fetch(`${apiOrigin()}/v1/projects/${projectId}/info`, {
- headers: { authorization: `Bearer ${token}` },
- cache: "no-store",
- });
- if (!res.ok) {
- throw new Error(`project info ${res.status}: ${(await res.text()).slice(0, 200)}`);
- }
- return res.json();
- }
|