diff --git a/package.json b/package.json index 536836c0f..43f86803a 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "@types/node": "22.7.9", "@types/react": "^18.0.5", "@types/react-dom": "^18.0.1", - "@types/uuid": "^8.3.4", "airtable": "^0.12.2", "axios": "^1.9.0", "bcrypt": "^5.1.1", @@ -82,8 +81,6 @@ "swagger-ui-express": "^5.0.1", "typedoc": "^0.23.8", "typescript": "^4.6.3", - "uuid": "^8.3.2", - "uuidv4": "^6.2.12", "web-vitals": "^2.1.4", "winston": "^3.5.1" }, diff --git a/server/src/api/record.ts b/server/src/api/record.ts index 5d9a68cd6..05ee55aed 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -7,7 +7,7 @@ import Robot from "../models/Robot"; import Run from "../models/Run"; const router = Router(); import { getDecryptedProxyConfig } from "../routes/proxy"; -import { v4 as uuid } from "uuid"; +import { randomUUID } from "crypto"; import { createRemoteBrowserForRun, destroyRemoteBrowser } from "../browser-management/controller"; import logger from "../logger"; import { browserPool } from "../server"; @@ -489,7 +489,7 @@ async function createWorkflowAndStoreMetadata(id: string, userId: string) { const browserId = createRemoteBrowserForRun(userId); - const runId = uuid(); + const runId = randomUUID(); const run = await Run.create({ status: 'running', diff --git a/server/src/browser-management/controller.ts b/server/src/browser-management/controller.ts index a6db615e4..cad1e14bd 100644 --- a/server/src/browser-management/controller.ts +++ b/server/src/browser-management/controller.ts @@ -3,7 +3,7 @@ * Holds the singleton instances of browser pool and socket.io server. */ import { Socket } from "socket.io"; -import { v4 as uuid } from "uuid"; +import { randomUUID } from "crypto"; import { createSocketConnection, createSocketConnectionForRun } from "../socket-connection/connection"; import { io, browserPool } from "../server"; @@ -21,7 +21,7 @@ import logger from "../logger"; * @category BrowserManagement-Controller */ export const initializeRemoteBrowserForRecording = (userId: string, mode: string = "dom"): string => { - const id = getActiveBrowserIdByState(userId, "recording") || uuid(); + const id = getActiveBrowserIdByState(userId, "recording") || randomUUID(); createSocketConnection( io.of(id), userId, @@ -67,7 +67,7 @@ export const createRemoteBrowserForRun = (userId: string): string => { throw new Error('userId is required'); } - const id = uuid(); + const id = randomUUID(); const slotReserved = browserPool.reserveBrowserSlot(id, userId, "run"); if (!slotReserved) { diff --git a/server/src/routes/storage.ts b/server/src/routes/storage.ts index bc33f3dc8..09211b0c5 100644 --- a/server/src/routes/storage.ts +++ b/server/src/routes/storage.ts @@ -4,7 +4,7 @@ import { createRemoteBrowserForRun, destroyRemoteBrowser, getActiveBrowserIdBySt import { chromium } from 'playwright-extra'; import stealthPlugin from 'puppeteer-extra-plugin-stealth'; import { browserPool } from "../server"; -import { v4 as uuid } from "uuid"; +import { randomUUID } from 'crypto'; import moment from 'moment-timezone'; import cron from 'node-cron'; import { getDecryptedProxyConfig } from './proxy'; @@ -394,11 +394,11 @@ router.post('/recordings/:id/duplicate', requireSignIn, async (req: Authenticate const currentTimestamp = new Date().toLocaleString(); const newRobot = await Robot.create({ - id: uuid(), + id: randomUUID(), userId: originalRobot.userId, recording_meta: { ...originalRobot.recording_meta, - id: uuid(), + id: randomUUID(), name: `${originalRobot.recording_meta.name} (${lastWord})`, createdAt: currentTimestamp, updatedAt: currentTimestamp, @@ -518,7 +518,7 @@ router.put('/runs/:id', requireSignIn, async (req: AuthenticatedRequest, res) => } // Generate runId first - const runId = uuid(); + const runId = randomUUID(); const canCreateBrowser = await browserPool.hasAvailableBrowserSlots(req.user.id, "run"); @@ -607,7 +607,7 @@ router.put('/runs/:id', requireSignIn, async (req: AuthenticatedRequest, res) => queued: false }); } else { - const browserId = uuid(); + const browserId = randomUUID(); await Run.create({ status: 'queued', diff --git a/server/src/routes/webhook.ts b/server/src/routes/webhook.ts index bba8ec8fd..2252f77a9 100644 --- a/server/src/routes/webhook.ts +++ b/server/src/routes/webhook.ts @@ -2,7 +2,7 @@ import { Router, Request, Response } from 'express'; import Robot from '../models/Robot'; import { requireSignIn } from '../middlewares/auth'; import axios from 'axios'; -import { v4 as uuid } from "uuid"; +import { randomUUID } from "crypto"; export const router = Router(); @@ -86,7 +86,7 @@ router.post('/add', requireSignIn, async (req: Request, res: Response) => { const newWebhook: WebhookConfig = { ...webhook, - id: webhook.id || uuid(), + id: webhook.id || randomUUID(), createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), lastCalledAt: null, diff --git a/server/src/schedule-worker.ts b/server/src/schedule-worker.ts index c75770e41..4fdf9e97d 100644 --- a/server/src/schedule-worker.ts +++ b/server/src/schedule-worker.ts @@ -2,11 +2,11 @@ * Worker process focused solely on scheduling logic */ import PgBoss, { Job } from 'pg-boss'; +import { randomUUID } from 'crypto'; import logger from './logger'; import Robot from './models/Robot'; import { handleRunRecording } from './workflow-management/scheduler'; import { computeNextRun } from './utils/schedule'; -import { v4 as uuid } from "uuid"; if (!process.env.DB_USER || !process.env.DB_PASSWORD || !process.env.DB_HOST || !process.env.DB_PORT || !process.env.DB_NAME) { throw new Error('One or more required environment variables are missing.'); @@ -33,7 +33,7 @@ interface ScheduledWorkflowData { */ export async function scheduleWorkflow(id: string, userId: string, cronExpression: string, timezone: string): Promise { try { - const runId = uuid(); + const runId = randomUUID(); const queueName = `scheduled-workflow-${id}`; diff --git a/server/src/workflow-management/classes/Generator.ts b/server/src/workflow-management/classes/Generator.ts index a5bc2edc4..2a0ccf77b 100644 --- a/server/src/workflow-management/classes/Generator.ts +++ b/server/src/workflow-management/classes/Generator.ts @@ -15,7 +15,7 @@ import { import { CustomActions } from "../../../../src/shared/types"; import Robot from "../../models/Robot"; import { getBestSelectorForAction } from "../utils"; -import { v4 as uuid } from "uuid"; +import { randomUUID } from "crypto"; import { capture } from "../../utils/analytics" import { decrypt, encrypt } from "../../utils/auth"; @@ -904,7 +904,7 @@ export class WorkflowGenerator { } else { this.recordingMeta = { name: fileName, - id: uuid(), + id: randomUUID(), createdAt: this.recordingMeta.createdAt || new Date().toLocaleString(), pairs: recording.workflow.length, updatedAt: new Date().toLocaleString(), diff --git a/server/src/workflow-management/scheduler/index.ts b/server/src/workflow-management/scheduler/index.ts index ce272689a..a6f17745d 100644 --- a/server/src/workflow-management/scheduler/index.ts +++ b/server/src/workflow-management/scheduler/index.ts @@ -1,4 +1,4 @@ -import { v4 as uuid } from "uuid"; +import { randomUUID } from "crypto"; import { chromium } from 'playwright-extra'; import stealthPlugin from 'puppeteer-extra-plugin-stealth'; import { io, Socket } from "socket.io-client"; @@ -47,7 +47,7 @@ async function createWorkflowAndStoreMetadata(id: string, userId: string) { } const browserId = createRemoteBrowserForRun( userId); - const runId = uuid(); + const runId = randomUUID(); const run = await Run.create({ status: 'scheduled', @@ -60,7 +60,7 @@ async function createWorkflowAndStoreMetadata(id: string, userId: string) { interpreterSettings: { maxConcurrency: 1, maxRepeats: 1, debug: true }, log: '', runId, - runByScheduleId: uuid(), + runByScheduleId: randomUUID(), serializableOutput: {}, binaryOutput: {}, }); diff --git a/src/components/integration/IntegrationSettings.tsx b/src/components/integration/IntegrationSettings.tsx index 6d0b892c6..4f7aa977c 100644 --- a/src/components/integration/IntegrationSettings.tsx +++ b/src/components/integration/IntegrationSettings.tsx @@ -29,7 +29,6 @@ import axios from "axios"; import { useGlobalInfoStore } from "../../context/globalInfo"; import { getStoredRecording } from "../../api/storage"; import { apiUrl } from "../../apiConfig.js"; -import { v4 as uuid } from "uuid"; import Cookies from "js-cookie"; @@ -197,7 +196,7 @@ export const IntegrationSettingsModal = ({ setLoading(true); const webhookWithId = { ...newWebhook, - id: uuid(), + id: crypto.randomUUID(), }; const response = await addWebhook(webhookWithId, recordingId); diff --git a/src/components/robot/pages/RobotIntegrationPage.tsx b/src/components/robot/pages/RobotIntegrationPage.tsx index 3c8425901..5ba59b9fd 100644 --- a/src/components/robot/pages/RobotIntegrationPage.tsx +++ b/src/components/robot/pages/RobotIntegrationPage.tsx @@ -33,7 +33,6 @@ import axios from "axios"; import { useGlobalInfoStore } from "../../../context/globalInfo"; import { getStoredRecording } from "../../../api/storage"; import { apiUrl } from "../../../apiConfig.js"; -import { v4 as uuid } from "uuid"; import { useTranslation } from "react-i18next"; import { useNavigate, useParams, useLocation } from "react-router-dom"; import { @@ -202,7 +201,7 @@ export const RobotIntegrationPage = ({ if (!recordingId) return; try { setLoading(true); - const webhookWithId = { ...newWebhook, id: uuid() }; + const webhookWithId = { ...newWebhook, id: crypto.randomUUID() }; const response = await addWebhook(webhookWithId, recordingId); if (response.ok) { setSettings((prev) => ({ ...prev, webhooks: [...(prev.webhooks || []), webhookWithId] }));