Some checks failed
Release Workflow / determine-release-type (push) Has been cancelled
Release Workflow / checks (push) Has been cancelled
Release Workflow / e2e-tests (push) Has been cancelled
Release Workflow / build-images (push) Has been cancelled
Release Workflow / publish-release (push) Has been cancelled
106 lines
3.3 KiB
TypeScript
106 lines
3.3 KiB
TypeScript
import { beforeEach, describe, expect, test } from "bun:test";
|
|
import { createApp } from "~/server/app";
|
|
import { config } from "~/server/core/config";
|
|
import { db } from "~/server/db/db";
|
|
import { account, invitation, member, organization, ssoProvider, usersTable, verification } from "~/server/db/schema";
|
|
import { createTestSession, createTestSessionWithOrgAdmin } from "~/test/helpers/auth";
|
|
|
|
const app = createApp();
|
|
const ssoRegisterUrl = new URL("/api/auth/sso/register", config.baseUrl).toString();
|
|
|
|
function buildRegisterBody(organizationId: string, suffix: string) {
|
|
return {
|
|
providerId: `oidc-${suffix}-${Bun.randomUUIDv7()}`,
|
|
issuer: "https://issuer.example.com",
|
|
domain: "example.com",
|
|
organizationId,
|
|
oidcConfig: {
|
|
clientId: "client-id",
|
|
clientSecret: "client-secret",
|
|
skipDiscovery: true,
|
|
discoveryEndpoint: "https://issuer.example.com/.well-known/openid-configuration",
|
|
authorizationEndpoint: "https://issuer.example.com/oauth2/authorize",
|
|
tokenEndpoint: "https://issuer.example.com/oauth2/token",
|
|
jwksEndpoint: "https://issuer.example.com/.well-known/jwks.json",
|
|
},
|
|
};
|
|
}
|
|
|
|
describe("SSO provider registration authorization", () => {
|
|
beforeEach(async () => {
|
|
await db.delete(member);
|
|
await db.delete(account);
|
|
await db.delete(invitation);
|
|
await db.delete(ssoProvider);
|
|
await db.delete(verification);
|
|
await db.delete(organization);
|
|
await db.delete(usersTable);
|
|
});
|
|
|
|
test("allows organization owners to register providers for their active organization", async () => {
|
|
const { headers, organizationId } = await createTestSession();
|
|
|
|
const response = await app.request(ssoRegisterUrl, {
|
|
method: "POST",
|
|
headers: {
|
|
...headers,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(buildRegisterBody(organizationId, "owner")),
|
|
});
|
|
|
|
expect(response.status).toBe(200);
|
|
});
|
|
|
|
test("rejects org admins for registration when they are not owners", async () => {
|
|
const { headers, organizationId } = await createTestSessionWithOrgAdmin();
|
|
|
|
const response = await app.request(ssoRegisterUrl, {
|
|
method: "POST",
|
|
headers: {
|
|
...headers,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(buildRegisterBody(organizationId, "admin")),
|
|
});
|
|
|
|
expect(response.status).toBe(403);
|
|
|
|
const body = await response.json();
|
|
expect(body.message).toBe("Only organization owners can register SSO providers");
|
|
});
|
|
|
|
test("rejects users who are owners elsewhere but only members of the target organization", async () => {
|
|
const { headers, user } = await createTestSession();
|
|
const targetOrgId = Bun.randomUUIDv7();
|
|
|
|
await db.insert(organization).values({
|
|
id: targetOrgId,
|
|
name: "Target Org",
|
|
slug: `target-org-${Date.now()}`,
|
|
createdAt: new Date(),
|
|
});
|
|
|
|
await db.insert(member).values({
|
|
id: Bun.randomUUIDv7(),
|
|
userId: user.id,
|
|
organizationId: targetOrgId,
|
|
role: "member",
|
|
createdAt: new Date(),
|
|
});
|
|
|
|
const response = await app.request(ssoRegisterUrl, {
|
|
method: "POST",
|
|
headers: {
|
|
...headers,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(buildRegisterBody(targetOrgId, "cross-org")),
|
|
});
|
|
|
|
expect(response.status).toBe(403);
|
|
|
|
const body = await response.json();
|
|
expect(body.message).toBe("Only organization owners can register SSO providers");
|
|
});
|
|
});
|