diff --git a/src/admin-api/index.ts b/src/admin-api/index.ts index 6ab5b87..b0e9f40 100644 --- a/src/admin-api/index.ts +++ b/src/admin-api/index.ts @@ -148,6 +148,14 @@ class AdminApi { throw err } } + + async createDevice(userId: string, deviceId: string): Promise { + try { + return await this.makeRequest("POST", `/v2/users/${userId}/devices`, { device_id: deviceId }) + } catch (err) { + throw err + } + } } export const adminApi = new AdminApi({ host: config.MATRIX_SERVER_URL, accessToken: config.ACCESS_TOKEN }) diff --git a/src/bot.ts b/src/bot.ts index 06263f7..65a40ea 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -13,7 +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 { runAccountCommand, ACCOUNT_COMMAND } from "./commands/account" import { CommandError } from "./utils" /* This is the maximum allowed time between time on matrix server @@ -114,8 +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) + case ACCOUNT_COMMAND: + return await runAccountCommand(roomId, event, args, this.client) default: return await runHelpCommand(roomId, event, this.client) } diff --git a/src/commands/rotate-token.ts b/src/commands/account.ts similarity index 52% rename from src/commands/rotate-token.ts rename to src/commands/account.ts index c449113..9a6ac6f 100644 --- a/src/commands/rotate-token.ts +++ b/src/commands/account.ts @@ -6,9 +6,14 @@ import config from "src/config/env" import { canExecuteCommand, CommandError } from "src/utils" const moduleName = "RotateTokenCommand" -export const ROTATE_TOKEN_COMMAND = "rotate-token" +export const ACCOUNT_COMMAND = "account" -export async function runRotateTokenCommand( +enum Command { + LoginUser = "login", + CreateDevice = "create-device", +} + +export async function runAccountCommand( roomId: string, event: MessageEvent, args: string[], @@ -21,10 +26,13 @@ export async function runRotateTokenCommand( } // 1. Retrive and validate arguments - const [, targetUserId] = args + const [, command, targetUserId, ...extraArgs] = args if (!event.sender.includes(`:${config.MATRIX_SERVER_DOMAIN}`)) { throw new CommandError(`Access denied.`) } + if (!Object.values(Command).includes(command as Command)) { + throw new CommandError(`Invalid subcommand. Should be one of: ${Object.values(Command).join(", ")}`) + } if (!targetUserId || !targetUserId.includes(`:${config.MATRIX_SERVER_DOMAIN}`)) { const [, wrongHomeServer] = targetUserId.split(":") throw new CommandError( @@ -44,15 +52,35 @@ export async function runRotateTokenCommand( 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}": ${JSON.stringify(response)}`, - ) - } catch (err) { - LogService.error(moduleName, err) - throw new CommandError(`Unable to retrieve user access token.`) + // 3.1 Generate an access token + if (command === Command.LoginUser) { + try { + const response = await adminApi.loginUser(targetUserId) + await client.sendHtmlText( + roomId, + `New access token for user "${targetUserId}": ${JSON.stringify(response)}`, + ) + } catch (err) { + LogService.error(moduleName, err) + throw new CommandError(`Unable to retrieve user access token.`) + } + } + + // 3.2 Create a new device + if (command === Command.CreateDevice) { + const deviceId = extraArgs[0] + if (!deviceId) { + throw new CommandError(`Missing device ID argument.`) + } + try { + const response = await adminApi.createDevice(targetUserId, deviceId) + await client.sendHtmlText( + roomId, + `Created a new device for user "${targetUserId}": ${JSON.stringify(response)}`, + ) + } catch (err) { + LogService.error(moduleName, err) + throw new CommandError(`Unable to retrieve user access token.`) + } } }