Skip to content

Commit

Permalink
Review changes
Browse files Browse the repository at this point in the history
This commit adds the following major changes

- Fix `globals.ts` to have proper seconds (since it was calculating based off milliseconds and not seconds). Updated `github-auth.ts` to reflect this change.

- Setup proper channel role mapping. Now it will name the new role `Defense: clientName` based on the `ext-channel-audit` name pattern.

- Fix typescript issues

- Remove max-age/max-uses from `/create-invite` command
  • Loading branch information
zuuring committed Mar 12, 2024
1 parent 9efb406 commit 239a6f7
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 106 deletions.
170 changes: 67 additions & 103 deletions discord-scripts/invite-management.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,24 @@
import { Robot } from "hubot"
import {
Client,
TextChannel,
VoiceChannel,
StageChannel,
ApplicationCommandOptionType,
} from "discord.js"
import { Client, TextChannel } from "discord.js"
import { WEEK } from "../lib/globals.ts"

const EXTERNAL_AUDIT_CHANNEL_REGEXP = /^ext-(?<client>.*)-audit$/

async function createInvite(
discordClient: Client,
channelId: string,
maxAge: number | string = 86400,
maxUses: number | string = 0,
maxAge = WEEK,
maxUses = 10,
): Promise<string | null> {
if (!discordClient) {
throw new Error("Discord client is not initialized.")
}
const channelForInvite = await discordClient.channels.fetch(channelId)

let channelOrigin: TextChannel | VoiceChannel | StageChannel | null = null
try {
const fetchedChannel = await discordClient.channels.fetch(channelId)
if (
fetchedChannel instanceof TextChannel ||
fetchedChannel instanceof VoiceChannel ||
fetchedChannel instanceof StageChannel
) {
channelOrigin = fetchedChannel
}
} catch (error) {
if (channelForInvite === null || !("createInvite" in channelForInvite)) {
throw new Error("Channel not found or access denied.")
}

if (!channelOrigin) {
return null
}
const numericMaxAge = parseInt(maxAge.toString(), 10)
const numericMaxUses = parseInt(maxUses.toString(), 10)
if (Number.isNaN(numericMaxAge) || Number.isNaN(numericMaxUses)) {
throw new Error("maxAge and maxUses must be valid numbers.")
}
const invite = await channelOrigin.createInvite({
maxAge: numericMaxAge,
maxUses: numericMaxUses,
const invite = await channelForInvite.createInvite({
maxAge,
maxUses,
unique: true,
})

Expand All @@ -62,25 +39,11 @@ export default async function sendInvite(discordClient: Client, robot: Robot) {
{
name: "create-invite",
description: "Creates a new invite",
options: [
{
name: "max-age",
description: "The maximum age of the invite in hours",
type: ApplicationCommandOptionType.Number,
required: false,
},
{
name: "max-uses",
description: "The maximum uses of the invite",
type: ApplicationCommandOptionType.Number,
required: false,
},
],
},
])
robot.logger.info("create invite command set")
}
// create an invite based of the command and channel where the command has been run
// Create an invite based of the command and channel where the command has been run
discordClient.on("interactionCreate", async (interaction) => {
if (
!interaction.isCommand() ||
Expand All @@ -93,11 +56,8 @@ export default async function sendInvite(discordClient: Client, robot: Robot) {
return
}

const maxAge =
((interaction.options.get("max-age", false)?.value as number) ?? 24) *
3600
const maxUses =
(interaction.options.get("max-uses", false)?.value as number) ?? 10
const maxAge = WEEK // default 7 days
const maxUses = 10 // default 10 uses

try {
const { channel } = interaction
Expand All @@ -109,71 +69,75 @@ export default async function sendInvite(discordClient: Client, robot: Robot) {
})
await interaction.reply(
`Here is your invite link: ${invite.url}\nThis invite expires in ${
maxAge / 3600
} hours and has a maximum of ${maxUses} uses.`,
maxAge / (3600 * 24)
} days and has a maximum of ${maxUses} uses.`,
)
} else {
await interaction.reply(
"Cannot create an invite for this type of channel.",
)
}
} catch (error) {
await interaction.reply("An error occurred while creating an invite.")
await interaction.reply("An error occurred while creating the invite.")
}
})

// Generates an invite if the channel name matches ext-*-audit format
discordClient.on("channelCreate", async (channel) => {
if (channel.parent && channel.parent.name === "defense") {
const regex = /^ext-.*-audit$/
if (regex.test(channel.name)) {
try {
const channelId = channel.id
const maxAge = 86400 // 1 day
const maxUses = 5
const inviteUrl = await createInvite(
discordClient,
channelId,
maxAge,
maxUses,
)
if (inviteUrl) {
robot.logger.info(
`New invite created for defense audit channel: ${channel.name}, URL: ${inviteUrl}`,
)
if (channel instanceof TextChannel) {
channel.send(
`Here is your invite link: ${inviteUrl}\n` +
`This invite expires in ${
maxAge / 3600
} hours and has a maximum of ${maxUses} uses.`,
)
}
}
// create a new role with the exact name of the channel with permissions only to that channel
const role = await channel.guild.roles.create({
name: channel.name,
reason: `Role for ${channel.name} channel`,
})

await channel.permissionOverwrites.create(role, {
ViewChannel: true,
SendMessages: true,
ReadMessageHistory: true,
})
if (channel instanceof TextChannel) {
channel.send(
`Role ${role.name} created and permissions set for ${channel.name}`,
)
}
if (
channel.parent &&
channel.parent.name === "defense" &&
channel instanceof TextChannel &&
EXTERNAL_AUDIT_CHANNEL_REGEXP.test(channel.name)
) {
try {
const channelId = channel.id
const maxAge = WEEK
const maxUses = 10
const inviteUrl = await createInvite(
discordClient,
channelId,
maxAge,
maxUses,
)
if (inviteUrl) {
robot.logger.info(
`Role ${role.name} created and permissions set for channel ${channel.name}`,
`New invite created for defense audit channel: ${channel.name}, URL: ${inviteUrl}`,
)
} catch (error) {
robot.logger.error(
`An error occurred setting up the defense audit channel: ${error}`,
channel.send(
`Here is your invite link: ${inviteUrl}\n` +
`This invite expires in ${
maxAge / (3600 * 24)
} days and has a maximum of ${maxUses} uses.`,
)
}
// Create a new role with the client name extracted and set permissions to that channel
const auditChannel = channel.name.split("-")
const clientName = auditChannel[0].includes("🔒")
? auditChannel[1]
: ""
const roleName = clientName
? `Defense: ${clientName}`
: `Defense: ${channel.name}`

const role = await channel.guild.roles.create({
name: roleName,
reason: `Role for ${channel.name} channel`,
})

await channel.permissionOverwrites.create(role, {
ViewChannel: true,
})
channel.send(
`**${role.name}** role created and permissions set for **${channel.name}**`,
)
robot.logger.info(
`${role.name} role created and permissions set for channel ${channel.name}`,
)
} catch (error) {
robot.logger.error(
`An error occurred setting up the defense audit channel: ${error}`,
)
}
}
})
Expand Down
6 changes: 5 additions & 1 deletion lib/globals.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
export const HOST = process.env.HUBOT_HOST
export const SECOND = 1000
export const MILLISECOND = 1000
export const SECOND = 1
export const MINUTE = 60 * SECOND
export const HOUR = 60 * MINUTE
export const DAY = 24 * HOUR
export const WEEK = 7 * DAY

Check failure on line 7 in lib/globals.ts

View workflow job for this annotation

GitHub Actions / lint

Insert `⏎`
4 changes: 2 additions & 2 deletions scripts/github-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
withConfigOrReportIssues,
issueReporterForRobot,
} from "../lib/config.ts"
import { HOST, MINUTE, SECOND } from "../lib/globals.ts"
import { HOST, MINUTE, MILLISECOND } from "../lib/globals.ts"

const PENDING_GITHUB_TOKENS_KEY = "pendingGitHubTokens"
const GITHUB_TOKENS_KEY = "gitHubTokens"
Expand Down Expand Up @@ -70,7 +70,7 @@ export default function setupGitHubAuth(robot: Robot) {
robot.brain.set(PENDING_GITHUB_TOKENS_KEY, pendingGitHubTokens)
}

setInterval(cleanPending, 30 * SECOND)
setInterval(cleanPending, 30 * MILLISECOND)
cleanPending()

robot.respond(/github auth/, (res) => {
Expand Down

0 comments on commit 239a6f7

Please sign in to comment.