ConusAI vendor v0.1.0-dev.20261027+9b1131fb
ci / gate (push) Waiting to run

This commit is contained in:
ConusAI vendor v0.1.0-dev.20261027+9b1131fb
2026-10-27 18:05:17 +00:00
commit 3102273ec7
538 changed files with 80203 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// GET /auth/callback: the provider sends the browser back here (MIB I3's path). The code is
// exchanged on the server, the tokens are sealed into the session row, and the browser receives
// one sealed cookie whose plaintext is a random handle. A failure of any step ends at the sign-in
// page with a code for the person to read, never at a 500 (src/server/auth-response.ts).
import { authRoutes } from "../../../src/server/app"
import { authResponse } from "../../../src/server/auth-response"
export const dynamic = "force-dynamic"
export const runtime = "nodejs"
export async function GET(request: Request): Promise<Response> {
return authResponse(request, async () => (await authRoutes()).callback(request))
}
+31
View File
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// GET /auth/dev-login?email=…&return_to=…: a sign-in for a developer with no identity provider.
// @conusai-kit/auth refuses to build it in a production deployment, and refuses again at boot if
// AUTH_DEV_LOGIN is set there, so this route cannot become a way in (spec §7).
import { createDevLogin, loadAuthConfig } from "@conusai-kit/auth"
import { authRoutes, webRuntime } from "../../../src/server/app"
import { safeReturnTo, signInErrorHref } from "../../../src/server/auth-errors"
import { authResponse, redirectTo } from "../../../src/server/auth-response"
export const dynamic = "force-dynamic"
export const runtime = "nodejs"
export async function GET(request: Request): Promise<Response> {
const config = loadAuthConfig()
if (!config.devLogin) return new Response("dev login is not enabled for this deployment", { status: 404 })
return authResponse(request, async () => {
const runtime = webRuntime()
const data = runtime.authData ?? runtime.data
if (!data) throw new Error("The selected profile has no auth data source")
const { sessions } = await authRoutes()
const response = await createDevLogin({ config, data, sessions }).signIn(request)
// An address the adapter would not take is a failed sign-in like any other, not a bare 400.
if (response.status === 400) return redirectTo(signInErrorHref("failed"))
// The adapter always lands on `/`; the person was going somewhere (the invitation they were sent).
const target = safeReturnTo(new URL(request.url).searchParams.get("return_to"))
if (response.status !== 302 || target === "/") return response
const headers = new Headers(response.headers)
headers.set("location", target)
return new Response(null, { status: 302, headers })
})
}
+79
View File
@@ -0,0 +1,79 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// The sign-in page (spec §7): where a visitor lands when they need to be signed in, and where a
// failed sign-in ends (src/server/auth-response.ts). It says what went wrong in the person's
// language -- from a fixed set of codes, never from the provider's text -- and offers the way in the
// deployment has: its identity provider, or, in development with none, any e-mail address.
import { loadAuthConfig } from "@conusai-kit/auth"
import { redirect } from "next/navigation"
import type { ReactElement } from "react"
import { AUTH_ERROR_MESSAGES, parseAuthError, safeReturnTo } from "../../../src/server/auth-errors"
import { betterAuthFormLabels, MIN_PASSWORD_LENGTH } from "../../../src/server/better-auth" // kit:convex-better-auth
import { pageContext } from "../../../src/server/page"
import { BetterAuthForm } from "../../../src/ui/better-auth-form" // kit:convex-better-auth
import { StateView } from "../../../src/ui/state-view"
export const dynamic = "force-dynamic"
export default async function SignIn({
searchParams,
}: {
searchParams: Promise<{ error?: string; return_to?: string }>
}): Promise<ReactElement> {
const { error, return_to: returnToParam } = await searchParams
const { i18n, signedIn } = await pageContext()
const returnTo = safeReturnTo(returnToParam)
// Somebody who is already in has nothing to do here, unless they were sent back with an error.
const code = parseAuthError(error)
if (signedIn && !code) redirect(returnTo)
const config = loadAuthConfig()
const next = returnTo === "/" ? "" : `?return_to=${encodeURIComponent(returnTo)}`
const betterAuth = config.provider === "convex-better-auth" // kit:convex-better-auth
return (
<StateView title={i18n.message("signin.title")}>
{code ? (
<p className="app-error" role="alert">
{i18n.message(AUTH_ERROR_MESSAGES[code])}
</p>
) : (
<p>{i18n.message("signin.intro")}</p>
)}
{config.oidc ? (
<p>
<a href={`/auth/sign-in/start${next}`}>{i18n.message("signin.continue")}</a>
</p>
) : null}
{!config.oidc && config.devLogin ? (
<form method="get" action="/auth/dev-login">
<h2>{i18n.message("signin.devTitle")}</h2>
<p>{i18n.message("signin.devHelp")}</p>
{returnTo === "/" ? null : <input type="hidden" name="return_to" value={returnTo} />}
<label className="kit-field" htmlFor="dev-email">
{i18n.message("app.email")}
<input id="dev-email" name="email" type="email" required autoComplete="email" />
</label>
<button type="submit">{i18n.message("signin.devSubmit")}</button>
</form>
) : null}
{/* kit:convex-better-auth:begin */}
{betterAuth ? (
<>
<BetterAuthForm
mode="sign-in"
returnTo={returnTo}
minPasswordLength={MIN_PASSWORD_LENGTH}
labels={betterAuthFormLabels(i18n, "sign-in")}
/>
<p>
<a href={`/auth/sign-up${next}`}>{i18n.message("signin.account.toSignUp")}</a>
</p>
</>
) : null}
{/* kit:convex-better-auth:end */}
{!config.oidc && !config.devLogin && config.provider === "oidc" ? (
<p role="status">{i18n.message("signin.notConfigured")}</p>
) : null}
</StateView>
)
}
+16
View File
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// GET /auth/sign-in/start: the redirect to the identity provider (spec §7). The transaction cookie it
// sets carries the state, the nonce and the PKCE verifier, sealed; the browser gets no token. The
// page people see before it is /auth/sign-in. A deployment with no provider has nothing to redirect
// to, and sends the visitor back to that page, which says so.
import { loadAuthConfig } from "@conusai-kit/auth"
import { authRoutes } from "../../../../src/server/app"
import { authResponse, redirectTo } from "../../../../src/server/auth-response"
export const dynamic = "force-dynamic"
export const runtime = "nodejs"
export async function GET(request: Request): Promise<Response> {
if (!loadAuthConfig().oidc) return redirectTo("/auth/sign-in")
return authResponse(request, async () => (await authRoutes()).signIn(request))
}
+29
View File
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// POST /auth/sign-out: revokes the session row and redirects to the provider's end-session
// endpoint, which sends the browser to /auth/signed-out.
//
// POST, with the fetch-metadata half of csrf.ts's check: revoking a session is a state change, so
// it must not hang on a GET, which a prefetch, a crawler or an <img> fires unprompted, and a
// cross-site form POST is refused the same way the API refuses one. The synchronizer token itself
// cannot be checked here -- a plain HTML form cannot send a header -- so the metadata a browser
// always sends is the check.
import { authRoutes } from "../../../src/server/app"
import { authResponse } from "../../../src/server/auth-response"
import { betterAuthSignOut } from "../../../src/server/better-auth-session" // kit:convex-better-auth
export const dynamic = "force-dynamic"
export const runtime = "nodejs"
export async function GET(): Promise<Response> {
return new Response("signing out is a POST", { status: 405, headers: { allow: "POST" } })
}
export async function POST(request: Request): Promise<Response> {
const site = request.headers.get("sec-fetch-site")
if (site !== null && site !== "same-origin" && site !== "none") {
return new Response("a cross-site sign-out is refused", { status: 403 })
}
const betterAuth = await betterAuthSignOut(request) // kit:convex-better-auth
if (betterAuth) return betterAuth // kit:convex-better-auth
return authResponse(request, async () => (await authRoutes()).signOut(request))
}
+42
View File
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// The sign-up page of the Convex Better Auth adapter (AUTH_PROVIDER=convex-better-auth): a new
// account with an e-mail address and a password. An OIDC deployment has its identity provider's own
// registration, so this page is not found there.
import { loadAuthConfig } from "@conusai-kit/auth"
import { notFound, redirect } from "next/navigation"
import type { ReactElement } from "react"
import { safeReturnTo } from "../../../src/server/auth-errors"
import { betterAuthFormLabels, MIN_PASSWORD_LENGTH } from "../../../src/server/better-auth"
import { pageContext } from "../../../src/server/page"
import { BetterAuthForm } from "../../../src/ui/better-auth-form"
import { StateView } from "../../../src/ui/state-view"
export const dynamic = "force-dynamic"
export default async function SignUp({
searchParams,
}: {
searchParams: Promise<{ return_to?: string }>
}): Promise<ReactElement> {
if (loadAuthConfig().provider !== "convex-better-auth") notFound()
const { return_to: returnToParam } = await searchParams
const { i18n, signedIn } = await pageContext()
const returnTo = safeReturnTo(returnToParam)
if (signedIn) redirect(returnTo)
const next = returnTo === "/" ? "" : `?return_to=${encodeURIComponent(returnTo)}`
return (
<StateView title={i18n.message("signin.account.signUpTitle")}>
<p>{i18n.message("signin.account.signUpIntro")}</p>
<BetterAuthForm
mode="sign-up"
returnTo={returnTo}
minPasswordLength={MIN_PASSWORD_LENGTH}
labels={betterAuthFormLabels(i18n, "sign-up")}
/>
<p>
<a href={`/auth/sign-in${next}`}>{i18n.message("signin.account.toSignIn")}</a>
</p>
</StateView>
)
}
+18
View File
@@ -0,0 +1,18 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// Where the identity provider sends the browser after an RP-initiated sign-out (MIB I3's path).
import type { ReactElement } from "react"
import { pageContext } from "../../../src/server/page"
export const dynamic = "force-dynamic"
export default async function SignedOut(): Promise<ReactElement> {
const { i18n } = await pageContext()
return (
<main>
<h1>{i18n.message("app.signedOut")}</h1>
<p>{i18n.message("app.signedOutBody")}</p>
<a href="/auth/sign-in">{i18n.message("app.signIn")}</a>
</main>
)
}