Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added the header to passed down the API #186

Merged
merged 3 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/controllers/changeNickname.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { updateNickName } from "../utils/updateNickname";

export async function changeNickname(request: IRequest, env: env) {
const authHeader = await request.headers.get("Authorization");
const reason = request.headers.get("X-Audit-Log-Reason");

if (!authHeader) {
return new JSONResponse(response.BAD_SIGNATURE);
Expand All @@ -15,7 +16,7 @@ export async function changeNickname(request: IRequest, env: env) {
try {
await verifyAuthToken(authHeader, env);
const { discordId, userName } = await request.json();
const res = await updateNickName(discordId, userName, env);
const res = await updateNickName(discordId, userName, env, reason);
return new JSONResponse(res);
} catch {
return new JSONResponse(response.BAD_SIGNATURE);
Expand Down
4 changes: 3 additions & 1 deletion src/controllers/generateDiscordInvite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ export async function generateInviteLink(request: IRequest, env: env) {
}
try {
await verifyAuthToken(authHeader, env);
const reason = request.headers.get("X-Audit-Log-Reason");

const body: inviteLinkBody = await request.json();
const res = await generateDiscordLink(body, env);
const res = await generateDiscordLink(body, env, reason);
return new JSONResponse(res);
} catch (err) {
return new JSONResponse(response.BAD_SIGNATURE);
Expand Down
31 changes: 21 additions & 10 deletions src/controllers/guildRoleHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { verifyAuthToken, verifyCronJobsToken } from "../utils/verifyAuthToken";
import { batchDiscordRequests } from "../utils/batchDiscordRequests";
import { DISCORD_BASE_URL } from "../constants/urls";
import { GROUP_ROLE_ADD } from "../constants/requestsActions";
import createDiscordHeaders from "../utils/createDiscordHeaders";

export async function createGuildRoleHandler(request: IRequest, env: env) {
const authHeader = request.headers.get("Authorization");
Expand All @@ -26,8 +27,8 @@ export async function createGuildRoleHandler(request: IRequest, env: env) {
try {
await verifyAuthToken(authHeader, env);
const body: createNewRole = await request.json();

const res = await createGuildRole(body, env);
const reason = request.headers.get("X-Audit-Log-Reason");
const res = await createGuildRole(body, env, reason);
return new JSONResponse(res);
} catch (err) {
return new JSONResponse(response.BAD_SIGNATURE);
Expand All @@ -41,8 +42,9 @@ export async function addGroupRoleHandler(request: IRequest, env: env) {
try {
await verifyAuthToken(authHeader, env);
const body: memberGroupRole = await request.json();
const reason = request.headers.get("X-Audit-Log-Reason");

const res = await addGroupRole(body, env);
const res = await addGroupRole(body, env, reason);
return new JSONResponse(res);
} catch (err) {
return new JSONResponse(response.BAD_SIGNATURE);
Expand All @@ -54,6 +56,7 @@ export async function getGuildRolesPostHandler(request: IRequest, env: env) {
if (!authHeader) {
return new JSONResponse(response.BAD_SIGNATURE);
}
const reason = request.headers.get("X-Audit-Log-Reason");

try {
await verifyCronJobsToken(authHeader, env);
Expand All @@ -62,7 +65,11 @@ export async function getGuildRolesPostHandler(request: IRequest, env: env) {
switch (action) {
case GROUP_ROLE_ADD.ADD_ROLE: {
const memberGroupRoleList = await request.json();
const res = await bulkAddGroupRoleHandler(memberGroupRoleList, env);
const res = await bulkAddGroupRoleHandler(
memberGroupRoleList,
env,
reason
);
return res;
}
default: {
Expand All @@ -77,7 +84,8 @@ export async function getGuildRolesPostHandler(request: IRequest, env: env) {

export async function bulkAddGroupRoleHandler(
memberGroupRoleList: memberGroupRole[],
env: env
env: env,
reason?: string
): Promise<JSONResponse> {
try {
if (!Array.isArray(memberGroupRoleList)) {
Expand Down Expand Up @@ -105,12 +113,13 @@ export async function bulkAddGroupRoleHandler(
const { userid, roleid } = memberGroupRole;
try {
const createGuildRoleUrl = `${DISCORD_BASE_URL}/guilds/${env.DISCORD_GUILD_ID}/members/${userid}/roles/${roleid}`;
const headers: HeadersInit = createDiscordHeaders({
reason,
token: env.DISCORD_TOKEN,
});
const options = {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${env.DISCORD_TOKEN}`,
},
headers,
};
return await fetch(createGuildRoleUrl, options);
} catch (error) {
Expand Down Expand Up @@ -141,13 +150,15 @@ export async function bulkAddGroupRoleHandler(

export async function removeGuildRoleHandler(request: IRequest, env: env) {
const authHeader = request.headers.get("Authorization");
const reason = request.headers.get("X-Audit-Log-Reason");

if (!authHeader) {
return new JSONResponse(response.BAD_SIGNATURE, { status: 401 });
}
try {
await verifyAuthToken(authHeader, env);
const body: memberGroupRole = await request.json();
const res = await removeGuildRole(body, env);
const res = await removeGuildRole(body, env, reason);
return new JSONResponse(res, {
status: 200,
headers: {
Expand Down
17 changes: 17 additions & 0 deletions src/utils/createDiscordHeaders.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const createDiscordHeaders = ({
reason,
token,
}: {
reason?: string;
token: string;
}) => {
const headers: HeadersInit = {
"Content-Type": "application/json",
Authorization: `Bot ${token}`,
};
if (reason) {
headers["X-Audit-Log-Reason"] = reason;
}
return headers;
};
export default createDiscordHeaders;
16 changes: 11 additions & 5 deletions src/utils/generateDiscordInvite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ import {
import { DISCORD_BASE_URL } from "../constants/urls";
import { env } from "../typeDefinitions/default.types";
import { inviteLinkBody } from "../typeDefinitions/discordLink.types";
import createDiscordHeaders from "./createDiscordHeaders";

export async function generateDiscordLink(body: inviteLinkBody, env: env) {
export async function generateDiscordLink(
body: inviteLinkBody,
env: env,
reason?: string
) {
const { channelId } = body;
const generateInviteUrl = `${DISCORD_BASE_URL}/channels/${channelId}/invites`;

Expand All @@ -20,13 +25,14 @@ export async function generateDiscordLink(body: inviteLinkBody, env: env) {
unique: INVITE_OPTIONS.UNIQUE, // Whether to create a unique invite or not
};
try {
const headers: HeadersInit = createDiscordHeaders({
reason,
token: env.DISCORD_TOKEN,
});
const response = await fetch(generateInviteUrl, {
method: "POST",
body: JSON.stringify(inviteOptions),
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${env.DISCORD_TOKEN}`,
},
headers,
});

if (response.ok) {
Expand Down
52 changes: 33 additions & 19 deletions src/utils/guildRole.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { HeadersInit } from "node-fetch";
import {
INTERNAL_SERVER_ERROR,
ROLE_ADDED,
Expand All @@ -12,23 +13,26 @@ import {
memberGroupRole,
} from "../typeDefinitions/discordMessage.types";
import { GuildRole, Role } from "../typeDefinitions/role.types";
import createDiscordHeaders from "./createDiscordHeaders";

export async function createGuildRole(
body: createNewRole,
env: env
env: env,
reason?: string
): Promise<guildRoleResponse | string> {
const createGuildRoleUrl = `${DISCORD_BASE_URL}/guilds/${env.DISCORD_GUILD_ID}/roles`;
const data = {
...body,
name: body.rolename,
};
const headers: HeadersInit = createDiscordHeaders({
reason,
token: env.DISCORD_TOKEN,
});
try {
const response = await fetch(createGuildRoleUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${env.DISCORD_TOKEN}`,
},
headers,
body: JSON.stringify(data),
});
if (response.ok) {
Expand All @@ -41,16 +45,21 @@ export async function createGuildRole(
}
}

export async function addGroupRole(body: memberGroupRole, env: env) {
export async function addGroupRole(
body: memberGroupRole,
env: env,
reason?: string
) {
const { userid, roleid } = body;
const createGuildRoleUrl = `${DISCORD_BASE_URL}/guilds/${env.DISCORD_GUILD_ID}/members/${userid}/roles/${roleid}`;
try {
const headers: HeadersInit = createDiscordHeaders({
reason,
token: env.DISCORD_TOKEN,
});
const response = await fetch(createGuildRoleUrl, {
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${env.DISCORD_TOKEN}`,
},
headers,
});
if (response.ok) {
return { message: ROLE_ADDED };
Expand All @@ -62,16 +71,21 @@ export async function addGroupRole(body: memberGroupRole, env: env) {
}
}

export async function removeGuildRole(details: memberGroupRole, env: env) {
export async function removeGuildRole(
details: memberGroupRole,
env: env,
reason?: string
) {
const { userid, roleid } = details;
const removeGuildRoleUrl = `${DISCORD_BASE_URL}/guilds/${env.DISCORD_GUILD_ID}/members/${userid}/roles/${roleid}`;
try {
const headers: HeadersInit = createDiscordHeaders({
reason,
token: env.DISCORD_TOKEN,
});
const response = await fetch(removeGuildRoleUrl, {
method: "DELETE",
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${env.DISCORD_TOKEN}`,
},
headers,
});
if (response.ok) {
return {
Expand All @@ -91,12 +105,12 @@ export async function getGuildRoles(env: env): Promise<Array<Role>> {
const guildRolesUrl = `${DISCORD_BASE_URL}/guilds/${env.DISCORD_GUILD_ID}/roles`;

try {
const headers: HeadersInit = createDiscordHeaders({
token: env.DISCORD_TOKEN,
});
const response = await fetch(guildRolesUrl, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${env.DISCORD_TOKEN}`,
},
headers,
});

if (!response.ok) {
Expand Down
13 changes: 8 additions & 5 deletions src/utils/updateNickname.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { INTERNAL_SERVER_ERROR, NAME_CHANGED } from "../constants/responses";
import { DISCORD_BASE_URL } from "../constants/urls";
import { env } from "../typeDefinitions/default.types";
import createDiscordHeaders from "./createDiscordHeaders";

export async function updateNickName(
discordId: string,
nickname: string,
env: env
env: env,
reason?: string
) {
const changeNickNameURL = `${DISCORD_BASE_URL}/guilds/${env.DISCORD_GUILD_ID}/members/${discordId}`;
const data = { nick: nickname };
const headers: HeadersInit = createDiscordHeaders({
reason,
token: env.DISCORD_TOKEN,
});
try {
const nameChangeResponse = await fetch(changeNickNameURL, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bot ${env.DISCORD_TOKEN}`,
},
headers,
body: JSON.stringify(data),
});
if (nameChangeResponse.ok) {
Expand Down
39 changes: 33 additions & 6 deletions tests/unit/handlers/generateDiscordInvite.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
const generateDiscordLink = jest
.fn()
.mockReturnValue({ data: {}, message: "Invite created successfully!" });
jest.mock("../../../src/utils/generateDiscordInvite", () => ({
generateDiscordLink,
}));
import { generateInviteLink } from "../../../src/controllers/generateDiscordInvite";
import JSONResponse from "../../../src/utils/JsonResponse";
import { generateDummyRequestObject, guildEnv } from "../../fixtures/fixture";
Expand All @@ -8,13 +14,34 @@ jest.mock("../../../src/utils/verifyAuthToken", () => ({
verifyAuthToken: jest.fn().mockReturnValue(true),
}));

jest.mock("../../../src/utils/generateDiscordInvite", () => ({
generateDiscordLink: jest
.fn()
.mockReturnValue({ data: {}, message: "Invite created successfully!" }),
}));

describe("generate discord link", () => {
it("should return data object with message on success ", async () => {
const mockRequest = generateDummyRequestObject({
method: "PUT",
url: "/invite",
headers: {
Authorization: "Bearer testtoken",
"Content-Type": "application/json",
"X-Audit-Log-Reason": "This is a reason",
},
json: async () => {
return { channelId: "xyz" };
},
});

const response: JSONResponse = await generateInviteLink(
mockRequest,
guildEnv
);

await response.json();
const body = await mockRequest.json();
expect(generateDiscordLink).toHaveBeenLastCalledWith(
body,
guildEnv,
"This is a reason"
);
});
it("should return 🚫 Bad Request Signature' if authtoken is there in the header", async () => {
const mockRequest = generateDummyRequestObject({
url: "/invite",
Expand Down
14 changes: 14 additions & 0 deletions tests/unit/utils/createDiscordHeaders.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import createDiscordHeaders from "../../../src/utils/createDiscordHeaders";

describe("createDiscordHeaders", () => {
it("should return an object with Authorization key if only token is passed", () => {
const header = createDiscordHeaders({ token: "1234567890" });
expect(header.Authorization).toBe("Bot 1234567890");
expect(header["X-Audit-Log-Reason"]).toBeFalsy();
});
it("should return an object with both prop Authorization and X-Audit-Log-Reason if reason and token prop are passed", () => {
const header = createDiscordHeaders({ token: "1234567890", reason: "456" });
expect(header.Authorization).toBe("Bot 1234567890");
expect(header["X-Audit-Log-Reason"]).toBe("456");
});
});
Loading
Loading