Files
outline/server/routes/api/oauthClients/oauthClients.test.ts
T
Tom Moor 77cee2806c chore: getJWTToken -> getSessionToken (#12371)
* getJWTToken -> getSessionToken

Ensure expiry is included in payload

* Refactor test harness to avoid direct usage of getSessionToken
2026-05-17 16:58:52 -04:00

339 lines
9.9 KiB
TypeScript

import { OAuthClient } from "@server/models";
import { buildTeam, buildUser, buildAdmin } from "@server/test/factories";
import { getTestServer } from "@server/test/support";
const server = getTestServer();
describe("oauthClients.list", () => {
it("should require authentication", async () => {
const res = await server.post("/api/oauthClients.list");
const body = await res.json();
expect(res.status).toEqual(401);
expect(body).toMatchSnapshot();
});
it("should return all clients for admin", async () => {
const team = await buildTeam();
const another = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
await OAuthClient.create({
teamId: another.id,
createdById: admin.id,
name: "Another Client",
redirectUris: ["https://example.com/callback"],
published: true,
});
await OAuthClient.create({
teamId: team.id,
createdById: admin.id,
name: "Published Client",
redirectUris: ["https://example.com/callback"],
published: true,
});
await OAuthClient.create({
teamId: team.id,
createdById: admin.id,
name: "Unpublished Client",
redirectUris: ["https://example.com/callback"],
published: false,
});
const res = await server.post("/api/oauthClients.list", admin);
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.length).toEqual(2);
expect(body.data.map((c: { name: string }) => c.name).sort()).toEqual([
"Published Client",
"Unpublished Client",
]);
expect(body.data[0].id).toBeDefined();
expect(body.data[0].redirectUris).toBeDefined();
});
});
describe("oauthClients.info", () => {
it("should require authentication", async () => {
const res = await server.post("/api/oauthClients.info");
const body = await res.json();
expect(res.status).toEqual(401);
expect(body).toMatchSnapshot();
});
it("should return confidential information about an OAuth client when admin", async () => {
const team = await buildTeam();
const user = await buildAdmin({ teamId: team.id });
const client = await OAuthClient.create({
teamId: team.id,
createdById: user.id,
name: "Test Client",
redirectUris: ["https://example.com/callback"],
});
const res = await server.post("/api/oauthClients.info", user, {
body: {
id: client.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.id).toBeDefined();
expect(body.data.name).toEqual("Test Client");
expect(body.data.published).toBeFalsy();
expect(body.data.clientSecret).toBeDefined();
expect(body.data.redirectUris).toEqual(["https://example.com/callback"]);
});
it("should return basic information about an OAuth client when member", async () => {
const team = await buildTeam();
const user = await buildUser({ teamId: team.id });
const client = await OAuthClient.create({
teamId: team.id,
createdById: user.id,
name: "Test Client",
redirectUris: ["https://example.com/callback"],
});
const res = await server.post("/api/oauthClients.info", user, {
body: {
id: client.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.id).toBeUndefined();
expect(body.data.name).toEqual("Test Client");
expect(body.data.clientSecret).toBeUndefined();
});
it("should return information about an OAuth client when published", async () => {
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
const user = await buildUser();
const client = await OAuthClient.create({
teamId: team.id,
createdById: admin.id,
name: "Test Client",
redirectUris: ["https://example.com/callback"],
published: true,
});
const res = await server.post("/api/oauthClients.info", user, {
body: {
id: client.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.name).toEqual("Test Client");
expect(body.data.published).toBeTruthy();
expect(body.data.id).toBeUndefined();
expect(body.data.redirectUris).toBeUndefined();
});
it("should allow querying by clientId", async () => {
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
const user = await buildUser();
const client = await OAuthClient.create({
teamId: team.id,
createdById: admin.id,
name: "Test Client",
redirectUris: ["https://example.com/callback"],
published: true,
});
const res = await server.post("/api/oauthClients.info", user, {
body: {
clientId: client.clientId,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.name).toEqual("Test Client");
expect(body.data.published).toBeTruthy();
expect(body.data.id).toBeUndefined();
expect(body.data.redirectUris).toBeUndefined();
});
it("should validate redirectUri parameter", async () => {
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
const user = await buildUser();
const client = await OAuthClient.create({
teamId: team.id,
createdById: admin.id,
name: "Test Client",
redirectUris: [
"https://example.com/callback",
"https://another.com/callback",
],
published: true,
});
// Test with valid redirectUri
const validRes = await server.post("/api/oauthClients.info", user, {
body: {
clientId: client.clientId,
redirectUri: "https://example.com/callback",
},
});
const validBody = await validRes.json();
expect(validRes.status).toEqual(200);
expect(validBody.data.name).toEqual("Test Client");
// Test with invalid redirectUri
const invalidRes = await server.post("/api/oauthClients.info", user, {
body: {
clientId: client.clientId,
redirectUri: "https://malicious.com/callback",
},
});
expect(invalidRes.status).toEqual(400);
});
});
describe("oauthClients.create", () => {
it("should require authentication", async () => {
const res = await server.post("/api/oauthClients.create");
const body = await res.json();
expect(res.status).toEqual(401);
expect(body).toMatchSnapshot();
});
it("should create a new OAuth client", async () => {
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
const res = await server.post("/api/oauthClients.create", admin, {
body: {
name: "Test Client",
redirectUris: ["https://example.com/callback"],
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.id).toBeDefined();
expect(body.data.name).toEqual("Test Client");
expect(body.data.redirectUris).toEqual(["https://example.com/callback"]);
});
});
describe("oauthclients.update", () => {
it("should require authentication", async () => {
const res = await server.post("/api/oauthClients.update");
const body = await res.json();
expect(res.status).toEqual(401);
expect(body).toMatchSnapshot();
});
it("should allow updating an OAuth client", async () => {
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
const client = await OAuthClient.create({
teamId: team.id,
createdById: admin.id,
name: "Test Client",
redirectUris: ["https://example.com/callback"],
published: true,
});
const res = await server.post("/api/oauthClients.update", admin, {
body: {
id: client.id,
published: false,
name: "Renamed",
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.name).toEqual("Renamed");
expect(body.data.published).toBeFalsy();
});
});
describe("oauthClients.rotate_secret", () => {
it("should require authentication", async () => {
const res = await server.post("/api/oauthClients.rotate_secret");
const body = await res.json();
expect(res.status).toEqual(401);
expect(body).toMatchSnapshot();
});
it("should rotate the client secret", async () => {
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
const client = await OAuthClient.create({
teamId: team.id,
createdById: admin.id,
name: "Test Client",
redirectUris: ["https://example.com/callback"],
});
const originalSecret = client.clientSecret;
const res = await server.post("/api/oauthClients.rotate_secret", admin, {
body: {
id: client.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.id).toBeDefined();
expect(body.data.clientSecret).toBeDefined();
expect(body.data.clientSecret).not.toEqual(originalSecret);
});
});
describe("oauthClients.delete", () => {
it("should require authentication", async () => {
const res = await server.post("/api/oauthClients.delete");
const body = await res.json();
expect(res.status).toEqual(401);
expect(body).toMatchSnapshot();
});
it("should delete an OAuth client", async () => {
const team = await buildTeam();
const admin = await buildAdmin({ teamId: team.id });
const client = await OAuthClient.create({
teamId: team.id,
createdById: admin.id,
name: "Test Client",
redirectUris: ["https://example.com/callback"],
});
const res = await server.post("/api/oauthClients.delete", admin, {
body: {
id: client.id,
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.success).toBe(true);
const deletedClient = await OAuthClient.findByPk(client.id);
expect(deletedClient).toBeNull();
});
});