2024-09-30 13:42:12 +02:00
|
|
|
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
2024-10-07 12:52:22 +02:00
|
|
|
import { db } from "@versia/kit/db";
|
|
|
|
|
import { eq } from "@versia/kit/drizzle";
|
2024-10-23 17:56:47 +02:00
|
|
|
import { Tokens } from "@versia/kit/tables";
|
|
|
|
|
import { Application } from "~/packages/database-interface/application";
|
2024-09-30 13:42:12 +02:00
|
|
|
import { fakeRequest, getTestUsers } from "~/tests/utils";
|
|
|
|
|
|
|
|
|
|
const { deleteUsers, users } = await getTestUsers(1);
|
|
|
|
|
|
2024-10-23 17:56:47 +02:00
|
|
|
const application = await Application.insert({
|
|
|
|
|
clientId: "test-client-id",
|
|
|
|
|
redirectUri: "https://example.com/callback",
|
|
|
|
|
scopes: "openid profile email",
|
|
|
|
|
secret: "test-secret",
|
|
|
|
|
name: "Test Application",
|
|
|
|
|
});
|
2024-09-30 13:42:12 +02:00
|
|
|
|
2024-10-23 17:56:47 +02:00
|
|
|
beforeAll(async () => {
|
2024-09-30 13:42:12 +02:00
|
|
|
await db.insert(Tokens).values({
|
|
|
|
|
code: "test-code",
|
2024-10-23 17:56:47 +02:00
|
|
|
redirectUri: application.data.redirectUri,
|
|
|
|
|
clientId: application.data.clientId,
|
2024-09-30 13:42:12 +02:00
|
|
|
accessToken: "test-access-token",
|
|
|
|
|
expiresAt: new Date(Date.now() + 3600 * 1000).toISOString(),
|
|
|
|
|
createdAt: new Date().toISOString(),
|
|
|
|
|
tokenType: "Bearer",
|
2024-10-23 17:56:47 +02:00
|
|
|
scope: application.data.scopes,
|
2024-09-30 13:42:12 +02:00
|
|
|
userId: users[0].id,
|
|
|
|
|
applicationId: application.id,
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
afterAll(async () => {
|
|
|
|
|
await deleteUsers();
|
2024-10-23 17:56:47 +02:00
|
|
|
await application.delete();
|
|
|
|
|
await db
|
|
|
|
|
.delete(Tokens)
|
|
|
|
|
.where(eq(Tokens.clientId, application.data.clientId));
|
2024-09-30 13:42:12 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe("/oauth/revoke", () => {
|
|
|
|
|
test("should revoke token with valid inputs", async () => {
|
|
|
|
|
const response = await fakeRequest("/oauth/revoke", {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({
|
2024-10-23 17:56:47 +02:00
|
|
|
client_id: application.data.clientId,
|
|
|
|
|
client_secret: application.data.secret,
|
2024-09-30 13:42:12 +02:00
|
|
|
token: "test-access-token",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(response.status).toBe(200);
|
|
|
|
|
const body = await response.json();
|
|
|
|
|
expect(body).toEqual({});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("should return error for missing token", async () => {
|
|
|
|
|
const response = await fakeRequest("/oauth/revoke", {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({
|
2024-10-23 17:56:47 +02:00
|
|
|
client_id: application.data.clientId,
|
|
|
|
|
client_secret: application.data.secret,
|
2024-09-30 13:42:12 +02:00
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(response.status).toBe(401);
|
|
|
|
|
const body = await response.json();
|
|
|
|
|
expect(body.error).toBe("unauthorized_client");
|
|
|
|
|
expect(body.error_description).toBe(
|
|
|
|
|
"You are not authorized to revoke this token",
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("should return error for invalid client credentials", async () => {
|
|
|
|
|
const response = await fakeRequest("/oauth/revoke", {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({
|
2024-10-23 17:56:47 +02:00
|
|
|
client_id: application.data.clientId,
|
2024-09-30 13:42:12 +02:00
|
|
|
client_secret: "invalid-secret",
|
|
|
|
|
token: "test-access-token",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(response.status).toBe(401);
|
|
|
|
|
const body = await response.json();
|
|
|
|
|
expect(body.error).toBe("unauthorized_client");
|
|
|
|
|
expect(body.error_description).toBe(
|
|
|
|
|
"You are not authorized to revoke this token",
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("should return error for token not found", async () => {
|
|
|
|
|
const response = await fakeRequest("/oauth/revoke", {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({
|
2024-10-23 17:56:47 +02:00
|
|
|
client_id: application.data.clientId,
|
|
|
|
|
client_secret: application.data.secret,
|
2024-09-30 13:42:12 +02:00
|
|
|
token: "invalid-token",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(response.status).toBe(401);
|
|
|
|
|
const body = await response.json();
|
|
|
|
|
expect(body.error).toBe("unauthorized_client");
|
|
|
|
|
expect(body.error_description).toBe(
|
|
|
|
|
"You are not authorized to revoke this token",
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("should return error for unauthorized client", async () => {
|
|
|
|
|
const response = await fakeRequest("/oauth/revoke", {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: {
|
|
|
|
|
"Content-Type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
client_id: "unauthorized-client-id",
|
2024-10-23 17:56:47 +02:00
|
|
|
client_secret: application.data.secret,
|
2024-09-30 13:42:12 +02:00
|
|
|
token: "test-access-token",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
expect(response.status).toBe(401);
|
|
|
|
|
const body = await response.json();
|
|
|
|
|
expect(body.error).toBe("unauthorized_client");
|
|
|
|
|
expect(body.error_description).toBe(
|
|
|
|
|
"You are not authorized to revoke this token",
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
});
|