From fca920474776e411aa8f5fe0c51e93b032482a3e Mon Sep 17 00:00:00 2001 From: Rohit Date: Tue, 21 Jan 2025 22:26:29 +0530 Subject: [PATCH] feat: change route to modify auth credentials --- server/src/routes/storage.ts | 75 ++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 7 deletions(-) diff --git a/server/src/routes/storage.ts b/server/src/routes/storage.ts index a9f2e0e9..91006613 100644 --- a/server/src/routes/storage.ts +++ b/server/src/routes/storage.ts @@ -18,6 +18,7 @@ import { AuthenticatedRequest } from './record'; import { computeNextRun } from '../utils/schedule'; import { capture } from "../utils/analytics"; import { tryCatch } from 'bullmq'; +import { encrypt } from '../utils/auth'; import { WorkflowFile } from 'maxun-core'; import { Page } from 'playwright'; chromium.use(stealthPlugin()); @@ -116,13 +117,70 @@ function formatRunResponse(run: any) { return formattedRun; } +interface CredentialUpdate { + [selector: string]: string; +} + +function updateTypeActionsInWorkflow(workflow: any[], credentials: CredentialUpdate) { + return workflow.map(step => { + if (!step.what) return step; + + // First pass: mark indices to remove + const indicesToRemove = new Set(); + step.what.forEach((action: any, index: any) => { + if (!action.action || !action.args?.[0]) return; + + // If it's a type/press action for a credential + if ((action.action === 'type' || action.action === 'press') && credentials[action.args[0]]) { + indicesToRemove.add(index); + // Check if next action is waitForLoadState + if (step.what[index + 1]?.action === 'waitForLoadState') { + indicesToRemove.add(index + 1); + } + } + }); + + // Filter out marked indices and create new what array + const filteredWhat = step.what.filter((_: any, index: any) => !indicesToRemove.has(index)); + + // Add new type actions after click actions + Object.entries(credentials).forEach(([selector, credential]) => { + const clickIndex = filteredWhat.findIndex((action: any) => + action.action === 'click' && action.args?.[0] === selector + ); + + if (clickIndex !== -1) { + const chars = credential.split('').reverse(); + chars.forEach((char, i) => { + // Add type action + filteredWhat.splice(clickIndex + 1 + (i * 2), 0, { + action: 'type', + args: [selector, char] // This would be encrypted in practice + }); + + // Add waitForLoadState + filteredWhat.splice(clickIndex + 2 + (i * 2), 0, { + action: 'waitForLoadState', + args: ['networkidle'] + }); + }); + } + }); + + return { + ...step, + what: filteredWhat + }; + }); +} + /** * PUT endpoint to update the name and limit of a robot. */ router.put('/recordings/:id', requireSignIn, async (req: AuthenticatedRequest, res) => { try { const { id } = req.params; - const { name, limit } = req.body; + const { name, limit, credentials } = req.body; // Validate input if (!name && limit === undefined) { @@ -141,17 +199,21 @@ router.put('/recordings/:id', requireSignIn, async (req: AuthenticatedRequest, r robot.set('recording_meta', { ...robot.recording_meta, name }); } + let workflow = [...robot.recording.workflow]; // Create a copy of the workflow + + if (credentials) { + workflow = updateTypeActionsInWorkflow(workflow, credentials); + } + // Update the limit if (limit !== undefined) { - const workflow = [...robot.recording.workflow]; // Create a copy of the workflow - // Ensure the workflow structure is valid before updating if ( workflow.length > 0 && workflow[0]?.what?.[0] ) { // Create a new workflow object with the updated limit - const updatedWorkflow = workflow.map((step, index) => { + workflow = workflow.map((step, index) => { if (index === 0) { // Assuming you want to update the first step return { ...step, @@ -173,14 +235,13 @@ router.put('/recordings/:id', requireSignIn, async (req: AuthenticatedRequest, r } return step; }); - - // Replace the workflow in the recording object - robot.set('recording', { ...robot.recording, workflow: updatedWorkflow }); } else { return res.status(400).json({ error: 'Invalid workflow structure for updating limit.' }); } } + robot.set('recording', { ...robot.recording, workflow }); + await robot.save(); const updatedRobot = await Robot.findOne({ where: { 'recording_meta.id': id } });