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
+77
View File
@@ -0,0 +1,77 @@
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// What a failed sign-in becomes (spec §7): a redirect to the sign-in page with a code from a fixed
// set, never the provider's text, and never to an address outside this app.
import { forbidden, unauthenticated } from "@conusai-kit/core"
import { describe, expect, it } from "vitest"
import {
AUTH_ERROR_MESSAGES,
AUTH_ERRORS,
authErrorOf,
parseAuthError,
safeReturnTo,
signInErrorHref,
} from "../apps/web/src/server/auth-errors.js"
import { appCatalogues } from "../apps/web/src/ui/messages.js"
const url = (query = ""): URL => new URL(`https://app.example.test/auth/callback${query}`)
describe("which code a failure gets", () => {
it("is `denied` when the provider said no, whatever the provider's text", () => {
expect(authErrorOf(new Error("anything"), url("?error=access_denied&error_description=secret+words"))).toBe(
"denied",
)
})
it("is `noTransaction` for a callback no sign-in started in this browser", () => {
const refusal = unauthenticated("no sign-in is in progress for this browser; start again at /auth/sign-in")
expect(authErrorOf(refusal, url())).toBe("noTransaction")
})
it("is `sessionExpired` for any other 401, `failed` for any other refusal of the app's own", () => {
expect(authErrorOf(unauthenticated("the session ended"), url())).toBe("sessionExpired")
expect(authErrorOf(forbidden("no"), url())).toBe("failed")
})
it("is `failed` for a deployment that has no identity provider to complete a sign-in with", () => {
expect(authErrorOf(unauthenticated("this deployment has no identity provider configured"), url())).toBe("failed")
})
it("is `provider` for what is not the app's own error: the exchange with the provider failed", () => {
expect(authErrorOf(new TypeError("fetch failed"), url())).toBe("provider")
})
})
describe("the sign-in page's address", () => {
it("carries the code and, when it is safe, where the person was going", () => {
expect(signInErrorHref("denied")).toBe("/auth/sign-in?error=denied")
expect(signInErrorHref("failed", "/invitations/acme/abc")).toBe(
"/auth/sign-in?error=failed&return_to=%2Finvitations%2Facme%2Fabc",
)
})
it.each(["https://evil.example", "//evil.example", "/\\evil.example", "javascript:alert(1)", "", null, undefined])(
"never returns to %j",
(target) => {
expect(safeReturnTo(target)).toBe("/")
expect(signInErrorHref("failed", target)).toBe("/auth/sign-in?error=failed")
},
)
it("shows only the five words, not whatever the query holds", () => {
expect(parseAuthError("denied")).toBe("denied")
expect(parseAuthError("<script>alert(1)</script>")).toBeUndefined()
expect(parseAuthError(undefined)).toBeUndefined()
})
})
describe("the words for each code", () => {
it("exist in English and in Lithuanian for every code", () => {
for (const code of AUTH_ERRORS) {
const [module, ...rest] = (AUTH_ERROR_MESSAGES[code] as string).split(".")
const key = rest.join(".")
expect(appCatalogues.en?.[module as string]?.[key], `en ${code}`).toBeTruthy()
expect(appCatalogues.lt?.[module as string]?.[key], `lt ${code}`).toBeTruthy()
}
})
})