Trouve-KA — moteur de recherche web indépendant, Québec-first. Crawler distribué, index OpenSearch, ranking bilingue, galerie d'images. En prod : www.trouve-ka.com
Python 51.9%
TypeScript 32.7%
JavaScript 4.8%
CSS 4.1%
Shell 2.9%
HTML 1.8%
SQL 1.5%
1// Auteur : Simon-Pierre Boucher — contact@spboucher.ai2// Retour SSO KA ID : vérifie le state signé localement puis le ka_token du hub3// (JWT HS256 — signature KA_SSO_SECRET, alg, iss, aud, exp), pose la session4// locale (cookie httpOnly tk_ka_session signé HMAC-SHA256, 30 jours) et5// redirige vers la destination demandée (ou l'accueil).6import { NextRequest, NextResponse } from "next/server";7import {8 KA_BASE_URL,9 SESSION_COOKIE,10 SESSION_DAYS,11 sessionFromClaims,12 verifyKaToken,13 verifyState,14} from "@/lib/ka-auth";1516export function GET(req: NextRequest) {17 const q = req.nextUrl.searchParams;18 const state = verifyState(q.get("state") ?? "");19 if (!state) {20 return NextResponse.json(21 { error: "state invalide ou expiré — recommencez la connexion" },22 { status: 400 },23 );24 }25 const claims = verifyKaToken(q.get("ka_token") ?? "");26 if (!claims) {27 return NextResponse.json(28 { error: "jeton KA invalide ou expiré — recommencez la connexion" },29 { status: 401 },30 );31 }32 const made = sessionFromClaims(claims);33 if (!made) {34 return NextResponse.json(35 { error: "jeton KA incomplet (ka_id manquant)" },36 { status: 401 },37 );38 }39 const res = NextResponse.redirect(new URL(state.next, KA_BASE_URL));40 res.cookies.set(SESSION_COOKIE, made.value, {41 httpOnly: true,42 secure: KA_BASE_URL.startsWith("https"),43 sameSite: "lax",44 path: "/",45 maxAge: SESSION_DAYS * 86400,46 });47 return res;48}49