Skip to content

Commit

Permalink
Test "rotate-token" command
Browse files Browse the repository at this point in the history
  • Loading branch information
ba1uev committed Jan 18, 2024
1 parent 56c830b commit 7630cc8
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/admin-api/index.ts
Expand Up @@ -4,6 +4,7 @@ import config from "src/config/env"

import {
ListRoomResponse,
LoginUserResponse,
RoomDeletionResponse,
RoomInfoResponse,
RoomInfoShort,
Expand Down Expand Up @@ -58,7 +59,9 @@ class AdminApi {
async getRoomPowerLevelsEvent(roomId: string): Promise<RoomPowerLevelsEvent | null> {
try {
const data = await this.getRoomState(roomId)
const powerLevelEvent = data.state.find((x) => x.type === "m.room.power_levels") as unknown as RoomPowerLevelsEvent
const powerLevelEvent = data.state.find(
(x) => x.type === "m.room.power_levels",
) as unknown as RoomPowerLevelsEvent
if (!powerLevelEvent) {
return null
}
Expand Down Expand Up @@ -136,6 +139,17 @@ class AdminApi {
} while (loop * limit <= total)
return rooms
}

async loginUser(userId: string): Promise<LoginUserResponse | null> {
try {
return (await this.makeRequest("GET", `/v1/users/${userId}/login`)) as LoginUserResponse
} catch (err) {
if (err.response.status === 404) {
return null
}
throw err
}
}
}

export const adminApi = new AdminApi({ host: config.MATRIX_SERVER_URL, accessToken: config.ACCESS_TOKEN })
4 changes: 4 additions & 0 deletions src/admin-api/types.ts
Expand Up @@ -185,3 +185,7 @@ export type CommandReport = {
succeedInvites: string[]
skippedInvitesNumber: number
}

export type LoginUserResponse = {
access_token: string
}
3 changes: 3 additions & 0 deletions src/bot.ts
Expand Up @@ -13,6 +13,7 @@ import { INVITE_COMMAND, runInviteCommand } from "./commands/invite"
import { INVITE_ROOM, runInviteRoomCommand } from "./commands/invite-room"
import { PROMOTE_COMMAND, runPromoteCommand } from "./commands/promote"
import { runSpaceCommand, SPACE_COMMAND } from "./commands/space"
import { runRotateTokenCommand, ROTATE_TOKEN_COMMAND } from "./commands/rotate-token"
import { CommandError } from "./utils"

/* This is the maximum allowed time between time on matrix server
Expand Down Expand Up @@ -113,6 +114,8 @@ export default class Bot {
return await runDeactivateUserCommand(roomId, event, args, this.client)
case SPACE_COMMAND:
return await runSpaceCommand(roomId, event, args, this.client)
case ROTATE_TOKEN_COMMAND:
return await runRotateTokenCommand(roomId, event, args, this.client)
default:
return await runHelpCommand(roomId, event, this.client)
}
Expand Down
58 changes: 58 additions & 0 deletions src/commands/rotate-token.ts
@@ -0,0 +1,58 @@
import { LogService, MatrixClient, MessageEvent, MessageEventContent } from "matrix-bot-sdk"

import { adminApi } from "src/admin-api"
import { UserAccountResponse } from "src/admin-api/types"
import config from "src/config/env"
import { canExecuteCommand, CommandError } from "src/utils"

const moduleName = "RotateTokenCommand"
export const ROTATE_TOKEN_COMMAND = "rotate-token"

export async function runRotateTokenCommand(
roomId: string,
event: MessageEvent<MessageEventContent>,
args: string[],
client: MatrixClient,
): Promise<void> {
// Ensure the user can execute the command
const canExecute = await canExecuteCommand(event.sender, roomId)
if (!canExecute) {
throw new CommandError(`Access denied`)
}

// 1. Retrive and validate arguments
const [, targetUserId] = args
if (!event.sender.includes(`:${config.MATRIX_SERVER_DOMAIN}`)) {
throw new CommandError(`Access denied.`)
}
if (!targetUserId || !targetUserId.includes(`:${config.MATRIX_SERVER_DOMAIN}`)) {
const [, wrongHomeServer] = targetUserId.split(":")
throw new CommandError(
`The provided user handle is not registered under ${config.MATRIX_SERVER_DOMAIN}, but ${wrongHomeServer}. \nMake sure that the user handle ends with ":${config.MATRIX_SERVER_DOMAIN}"`,
)
}

// 2. Retrieve user details
let user: UserAccountResponse | null = null
try {
user = await adminApi.getUserAccount(targetUserId)
} catch (e) {
LogService.error(moduleName, e)
throw new CommandError(`Unable to retrieve user account details.`)
}
if (!user) {
throw new CommandError(`The user "${targetUserId}" cannot be found.`)
}

// 3. Generate an access token
try {
const response = await adminApi.loginUser(targetUserId)
await client.sendHtmlText(
roomId,
`New access token for user "${targetUserId}": <code>${JSON.stringify(response)}</code>`,
)
} catch (err) {
LogService.error(moduleName, err)
throw new CommandError(`Unable to retrieve user access token.`)
}
}

0 comments on commit 7630cc8

Please sign in to comment.