chore: lock the plugin boundary and remove 2.9.0 leftovers

This commit is contained in:
LukeGus committed 2026-09-25 07:24:46 -05:00
1 parent 6489b62ece
commit 2961297989
399 files changed
+3964 -5627

No files matched your search

@@ -1,6 +1,8 @@
/**
* contributes.http.legacyPaths: an old URL under "/<plugin id>/" reaches the
* plugin's router with that prefix removed, and nothing else is caught.
* contributes.http.legacyRedirects: an old URL anywhere redirects to the
* plugin's own URL, keeping the subpath and the query.
*/
import express from "express";
@@ -16,10 +18,20 @@ vi.mock("../../../plugins/http.js", () => ({
const { mountPluginLegacyPaths } =
await import("../../../database/routes/plugin-api-routes.js");
function appWith(active: Array<{ id: string; legacyPaths: string[] }>) {
type Active = Parameters<typeof mountPluginLegacyPaths>[1] extends () => Array<
infer T
>
? T
: never;
function appWith(
active: Array<Omit<Active, "legacyRedirects"> & Partial<Active>>,
) {
const app = express();
app.get("/core/route", (_req, res) => res.json({ from: "core" }));
mountPluginLegacyPaths(app, () => active);
mountPluginLegacyPaths(app, () =>
active.map((entry) => ({ legacyRedirects: [], ...entry })),
);
app.use((_req, res) => res.status(404).json({ from: "fallthrough" }));
return app;
}
@@ -58,3 +70,37 @@ describe("mountPluginLegacyPaths", () => {
expect(response.status).toBe(404);
});
});
describe("legacy redirects", () => {
const app = appWith([
{
id: "idp",
legacyPaths: [],
legacyRedirects: [
{ from: "/host/idp-callback", to: "/callback" },
{ from: "/old-id/u", to: "/u", status: 308 },
],
},
]);
it("redirects to the plugin's URL with the query", async () => {
const response = await request(app).get(
"/host/idp-callback?code=abc&state=xyz",
);
expect(response.status).toBe(307);
expect(response.headers.location).toBe(
"/plugin-api/idp/callback?code=abc&state=xyz",
);
});
it("keeps a subpath and honours a permanent status", async () => {
const response = await request(app).get("/old-id/u/alice/ca");
expect(response.status).toBe(308);
expect(response.headers.location).toBe("/plugin-api/idp/u/alice/ca");
});
it("does not catch a path that only shares a prefix", async () => {
const response = await request(app).get("/host/idp-callbacks");
expect(response.body).toEqual({ from: "fallthrough" });
});
});