Skip to content

Conversation

coodos
Copy link
Contributor

@coodos coodos commented Oct 14, 2025

Description of change

Issue Number

Type of change

  • Breaking (any change that would cause existing functionality to not work as expected)
  • New (a change which implements a new feature)
  • Update (a change which updates existing functionality)
  • Fix (a change which fixes an issue)
  • Docs (changes to the documentation)
  • Chore (refactoring, build scripts or anything else that isn't user-facing)

How the change has been tested

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

Summary by CodeRabbit

  • New Features

    • DreamSync: QR code login with live updates, new Wishlist Editor with rich text, save/update, and logout.
    • AI-powered matching and notifications enabled via the new DreamSync API (wishlists, matches, groups).
    • Mobile-friendly deep links and app store redirects during login.
    • Chats now display admins alongside participants.
  • Changes

    • DreamSync client simplified: routes consolidated to the Wishlist Editor; legacy pages (dashboard, profile, groups, matches, suggestions) removed.
    • Wallet QR scan/signing flows updated for improved reliability and W3ID-based signing.
  • Documentation

    • Added DreamSync API README with setup, endpoints, and workflow details.

Copy link
Contributor

coderabbitai bot commented Oct 14, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Large refactor introducing a new DreamSync REST API (controllers, services, entities, migrations, middleware, bootstrap), a client-side auth/context + wishlist editor UI, and removal of the old DreamSync server and many client pages. eID wallet QR/signing flow is refactored to use KeyManager. Web3-adapter internals are streamlined. Minor API tweaks in other platforms and mappings.

Changes

Cohort / File(s) Summary
eID Wallet: KeyManager signing flow
infrastructure/eid-wallet/src/routes/(app)/scan-qr/+page.svelte
Replaces crypto-hw API calls with KeyManagerFactory/KeyManager. Adjusts auth/sign payloads to include w3id and signatures; updates deep-link/signing flow and error handling.
eVoting: component removal
infrastructure/eVoting/src/components/signing-interface.tsx
Deletes signing-interface React component.
Blabsy API tweaks
platforms/blabsy-w3ds-auth-api/src/controllers/AuthController.ts, .../WebhookController.ts
Adds request body log in AuthController.login. Adds admins parsing/propagation in WebhookController.
DreamSync Client: auth and editor
platforms/dreamSync/client/src/App.tsx, .../components/auth/login-screen.tsx, .../components/auth/protected-route.tsx, .../components/wysiwyg-editor.tsx, .../hooks/useAuth.ts, .../lib/apiClient.ts, .../lib/auth-context.tsx, .../lib/authUtils.ts, .../lib/utils/mobile-detection.ts, .../pages/login.tsx, .../pages/wishlist-editor.tsx
Adds client auth context, API client with token interceptors, login via QR/SSE, protected route, WYSIWYG editor, auth utils, mobile detection, and WishlistEditor page; App wrapped with AuthProvider; login page renders LoginScreen.
DreamSync Client: pages removed
platforms/dreamSync/client/src/pages/{dashboard.tsx,groups.tsx,matches-new.tsx,profile.tsx,suggestions.tsx,wishlist-item.tsx,wishlist.tsx}
Removes multiple legacy pages and associated logic/UI.
DreamSync Client config
platforms/dreamSync/vite.config.ts, platforms/dreamSync/package.json
Adds envDir to Vite config; overhauls package.json scripts/deps to Vite/React-focused stack.
DreamSync Server: removal
platforms/dreamSync/server/*
Deletes entire server layer (auth, DB, routes, seeders, OpenAI flows, storage, vite integration, index).
DreamSync API: new backend
platforms/dreamsync-api/{README.md,package.json,reset.sh,tsconfig.json}
Adds new project scaffolding, scripts, README, reset script, TS config.
DreamSync API: bootstrap & middleware
platforms/dreamsync-api/src/index.ts, .../middleware/auth.ts, .../utils/jwt.ts, .../types/express.d.ts
Adds server startup, routes wiring, JWT auth middleware/guard, Express request user typing.
DreamSync API: database
platforms/dreamsync-api/src/database/{data-source.ts,entities/*,migrations/*}
Adds TypeORM data source and entities (User, Group, Message, Wishlist, Match, UserEVaultMapping, WebhookProcessing) with migrations for schema creation and updates.
DreamSync API: controllers
platforms/dreamsync-api/src/controllers/{AuthController.ts,UserController.ts,WishlistController.ts,MatchController.ts,WebhookController.ts}
Implements SSE auth flow, user profile/search/update, wishlist CRUD, match endpoints, and comprehensive webhook ingestion/processing.
DreamSync API: services
platforms/dreamsync-api/src/services/{UserService.ts,WishlistService.ts,MatchingService.ts,AIMatchingService.ts,MatchNotificationService.ts,ConsentService.ts,MatchingJob.ts,WebhookProcessingService.ts,PlatformEVaultService.ts,SharedMatchingService.ts}
Adds user/wishlist data services, AI matching and notification orchestration, consent handling, webhook processing state, EVault platform provisioning, and a scheduled matching job.
DreamSync API: web3-adapter integration
platforms/dreamsync-api/src/web3adapter/{index.ts,mappings/*.json,watchers/subscriber.ts}
Wires a TypeORM subscriber to emit webhooks via Web3Adapter; adds user/group/message mapping JSON; re-exports adapter.
DreamSync API: tests
platforms/dreamsync-api/{test-matchmaking.ts,test-matchmaking-mock.ts}
Adds matchmaking test runners (DB-backed and mock).
Web3-Adapter: refactors & enhancements
infrastructure/web3-adapter/src/{index.js,evault/evault.js,db/index.js,db/mapping.db.js,logging/{index.js,logger.js,transport.js},mapper/{mapper.js,mapper.types.js}}
Streamlines interop helpers and formatting; adds env loading in logging transport; mapping DB gains initialize(); mapper.fromGlobal now returns { ownerEvault, data }; exports createGroupEVault.
Pictique API mapping
platforms/pictique-api/src/web3adapter/mappings/chat.mapping.json
Adds admins mapping to chat mapping.
Registry
platforms/registry/src/index.ts
Adds VITE_DREAMSYNC_BASE_URL to platforms list.
Marketplace
platforms/marketplace/package.json
Adds nanoid dependency.
eVoting API removals
platforms/evoting-api/src/{auth.ts,utils/typeorm-adapter.ts}
Removes better-auth setup and TypeORM adapter implementation.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User as User (Browser)
  participant Client as DreamSync Client (LoginScreen)
  participant API as AuthController
  participant SSE as SSE Stream

  User->>Client: Open /login
  Client->>API: GET /api/auth/offer
  API-->>Client: { offer, sessionId }
  Note over Client: Show QR (offer)
  User->>API: POST /api/auth/login { ename, session }
  API-->>SSE: emit(session, { token, user })
  Client->>API: GET /api/auth/sessions/{sessionId} (SSE)
  SSE-->>Client: { token, user }
  Client->>Client: Store token, userId
  Client-->>User: Redirect to /
Loading
sequenceDiagram
  autonumber
  participant Svelte as scan-qr +page.svelte
  participant KMF as KeyManagerFactory
  participant KM as KeyManager
  participant Backend as Redirect URI / auth endpoint

  Svelte->>KMF: getKeyManagerForContext(ctx)
  KMF-->>Svelte: KeyManager
  Svelte->>KM: exists(ename)?
  alt Missing key
    Svelte->>KM: generate(ename)
  end
  Svelte->>KM: getPublicKey(ename) / get W3ID
  Svelte->>KM: signPayload(ename, payload)
  Svelte->>Backend: POST { ename, w3id, signature, session }
  Backend-->>Svelte: 200/redirect
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~180 minutes

Possibly related PRs

Suggested reviewers

  • sosweetham

Poem

A rabbit taps keys by moonlit light,
New vaults spin up, old servers take flight.
QR codes blink, SSE streams sing,
Keys sign softly—what gifts they bring.
Wishes weave matches, groups say “hi!”
Hippity-hop—DreamSync hops sky-high. 🐇✨

Pre-merge checks and finishing touches and finishing touches

❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description is just the unchanged template without any sections filled in, so it fails to describe the actual changes, testing steps, or type of change. Please fill out the template by providing a summary of the changes, linking any issue number, specifying the type of change (e.g., New, Update), describing how the changes were tested, and checking off the relevant checklist items.
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The title “Feat/dreamsync” uses a generic conventional-commit style prefix and does not clearly convey the primary changes introduced by this pull request, leaving readers without insight into the substantive DreamSync integration and refactoring. Please update the title to a concise sentence that highlights the main change, for example “Integrate DreamSync API controllers and refactor client components for DreamSync platform.”

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c3e3b19 and 826e26c.

⛔ Files ignored due to path filters (9)
  • infrastructure/eid-wallet/src-tauri/gen/apple/eid-wallet.xcodeproj/project.pbxproj is excluded by !**/gen/**
  • infrastructure/eid-wallet/src-tauri/gen/apple/eid-wallet_iOS/Info.plist is excluded by !**/gen/**
  • infrastructure/web3-adapter/src/evault/evault.js.map is excluded by !**/*.map
  • infrastructure/web3-adapter/src/index.js.map is excluded by !**/*.map
  • infrastructure/web3-adapter/src/logging/transport.js.map is excluded by !**/*.map
  • infrastructure/web3-adapter/src/mapper/mapper.js.map is excluded by !**/*.map
  • platforms/dreamSync/client/public/W3DS.svg is excluded by !**/*.svg
  • platforms/dreamSync/package-lock.json is excluded by !**/package-lock.json
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (99)
  • infrastructure/eVoting/src/components/signing-interface.tsx (0 hunks)
  • infrastructure/web3-adapter/src/db/index.js (1 hunks)
  • infrastructure/web3-adapter/src/db/mapping.db.js (7 hunks)
  • infrastructure/web3-adapter/src/evault/evault.js (16 hunks)
  • infrastructure/web3-adapter/src/index.js (11 hunks)
  • infrastructure/web3-adapter/src/logging/index.js (1 hunks)
  • infrastructure/web3-adapter/src/logging/logger.js (1 hunks)
  • infrastructure/web3-adapter/src/logging/transport.js (2 hunks)
  • infrastructure/web3-adapter/src/mapper/mapper.js (11 hunks)
  • infrastructure/web3-adapter/src/mapper/mapper.types.js (1 hunks)
  • platforms/blabsy-w3ds-auth-api/src/controllers/AuthController.ts (1 hunks)
  • platforms/blabsy-w3ds-auth-api/src/controllers/WebhookController.ts (3 hunks)
  • platforms/dreamSync/client/src/App.tsx (3 hunks)
  • platforms/dreamSync/client/src/components/auth/login-screen.tsx (1 hunks)
  • platforms/dreamSync/client/src/components/auth/protected-route.tsx (1 hunks)
  • platforms/dreamSync/client/src/components/wysiwyg-editor.tsx (1 hunks)
  • platforms/dreamSync/client/src/hooks/useAuth.ts (1 hunks)
  • platforms/dreamSync/client/src/lib/apiClient.ts (1 hunks)
  • platforms/dreamSync/client/src/lib/auth-context.tsx (1 hunks)
  • platforms/dreamSync/client/src/lib/authUtils.ts (1 hunks)
  • platforms/dreamSync/client/src/lib/utils/mobile-detection.ts (1 hunks)
  • platforms/dreamSync/client/src/pages/dashboard.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/groups.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/login.tsx (1 hunks)
  • platforms/dreamSync/client/src/pages/matches-new.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/profile.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/suggestions.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/wishlist-editor.tsx (1 hunks)
  • platforms/dreamSync/client/src/pages/wishlist-item.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/wishlist.tsx (0 hunks)
  • platforms/dreamSync/package.json (1 hunks)
  • platforms/dreamSync/server/aiSuggestionsService.ts (0 hunks)
  • platforms/dreamSync/server/auth.ts (0 hunks)
  • platforms/dreamSync/server/db.ts (0 hunks)
  • platforms/dreamSync/server/ensureFullyPopulatedData.ts (0 hunks)
  • platforms/dreamSync/server/fixPasswords.ts (0 hunks)
  • platforms/dreamSync/server/generateTestSuggestions.ts (0 hunks)
  • platforms/dreamSync/server/index.ts (0 hunks)
  • platforms/dreamSync/server/openai.ts (0 hunks)
  • platforms/dreamSync/server/replitAuth.ts (0 hunks)
  • platforms/dreamSync/server/routes.ts (0 hunks)
  • platforms/dreamSync/server/seedComprehensiveData.ts (0 hunks)
  • platforms/dreamSync/server/seedData.ts (0 hunks)
  • platforms/dreamSync/server/seedEnhancedData.ts (0 hunks)
  • platforms/dreamSync/server/seedExtensiveData.ts (0 hunks)
  • platforms/dreamSync/server/storage.ts (0 hunks)
  • platforms/dreamSync/server/vite.ts (0 hunks)
  • platforms/dreamSync/vite.config.ts (2 hunks)
  • platforms/dreamsync-api/README.md (1 hunks)
  • platforms/dreamsync-api/package.json (1 hunks)
  • platforms/dreamsync-api/reset.sh (1 hunks)
  • platforms/dreamsync-api/src/controllers/AuthController.ts (1 hunks)
  • platforms/dreamsync-api/src/controllers/MatchController.ts (1 hunks)
  • platforms/dreamsync-api/src/controllers/UserController.ts (1 hunks)
  • platforms/dreamsync-api/src/controllers/WebhookController.ts (1 hunks)
  • platforms/dreamsync-api/src/controllers/WishlistController.ts (1 hunks)
  • platforms/dreamsync-api/src/database/data-source.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/Group.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/Match.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/Message.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/User.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/UserEVaultMapping.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/WebhookProcessing.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/Wishlist.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760045198484-migration.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760080210824-migration.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760087325046-AddUserEVaultMapping.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760087896024-AddMatchConsentFields.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760422131457-migration.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760427215447-migration.ts (1 hunks)
  • platforms/dreamsync-api/src/index.ts (1 hunks)
  • platforms/dreamsync-api/src/middleware/auth.ts (1 hunks)
  • platforms/dreamsync-api/src/services/AIMatchingService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/ConsentService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/GroupService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/MatchNotificationService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/MatchingJob.ts (1 hunks)
  • platforms/dreamsync-api/src/services/MatchingService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/MessageService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/PlatformEVaultService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/SharedMatchingService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/UserService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/WebhookProcessingService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/WishlistService.ts (1 hunks)
  • platforms/dreamsync-api/src/types/express.d.ts (1 hunks)
  • platforms/dreamsync-api/src/utils/jwt.ts (1 hunks)
  • platforms/dreamsync-api/src/web3adapter/index.ts (1 hunks)
  • platforms/dreamsync-api/src/web3adapter/mappings/group.mapping.json (1 hunks)
  • platforms/dreamsync-api/src/web3adapter/mappings/message.mapping.json (1 hunks)
  • platforms/dreamsync-api/src/web3adapter/mappings/user.mapping.json (1 hunks)
  • platforms/dreamsync-api/src/web3adapter/watchers/subscriber.ts (1 hunks)
  • platforms/dreamsync-api/test-matchmaking-mock.ts (1 hunks)
  • platforms/dreamsync-api/test-matchmaking.ts (1 hunks)
  • platforms/dreamsync-api/tsconfig.json (1 hunks)
  • platforms/evoting-api/src/auth.ts (0 hunks)
  • platforms/evoting-api/src/utils/typeorm-adapter.ts (0 hunks)
  • platforms/marketplace/package.json (1 hunks)
  • platforms/pictique-api/src/web3adapter/mappings/chat.mapping.json (1 hunks)
  • platforms/registry/src/index.ts (1 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coodos coodos merged commit 5b9bc1a into main Oct 14, 2025
0 of 3 checks passed
@coodos coodos deleted the feat/dreamsync branch October 14, 2025 23:16
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 37

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
platforms/blabsy-w3ds-auth-api/src/controllers/AuthController.ts (1)

62-62: Remove log that exposes authentication tokens.

Logging the Firebase custom token is a critical security vulnerability. These tokens are authentication credentials that can be used to impersonate users and must never appear in logs.

Apply this diff to remove the token log:

             const token = await auth().createCustomToken(ename);
-            console.log(token);
platforms/registry/src/index.ts (1)

109-120: Filter undefined environment variables from the platforms array.

If VITE_DREAMSYNC_BASE_URL (or any other environment variable) is not set, the array will contain undefined values. This can break consumers expecting only valid URL strings.

Apply this diff to filter out undefined values:

 server.get("/platforms", async (request, reply) => {
-    const platforms = [ 
+    const platforms = [
         process.env.PUBLIC_PICTIQUE_BASE_URL, 
         process.env.PUBLIC_BLABSY_BASE_URL, 
         process.env.PUBLIC_GROUP_CHARTER_BASE_URL, 
         process.env.PUBLIC_CERBERUS_BASE_URL, 
         process.env.PUBLIC_EVOTING_BASE_URL,
         process.env.VITE_DREAMSYNC_BASE_URL
-    ]
+    ].filter((url): url is string => url !== undefined && url !== null && url !== "")
 
     return platforms
 });
platforms/pictique-api/src/web3adapter/watchers/subscriber.ts (2)

201-226: Fix async error handling in setTimeout callback.

The try-catch wraps the setTimeout call but doesn't catch errors that occur inside the async callback. Errors thrown in the async code within setTimeout (lines 203-221) will be unhandled, potentially causing the process to crash or leading to silent failures.

Apply this pattern to properly handle async errors:

-        try {
-            setTimeout(async () => {
-                try {
-                    let globalId = await this.adapter.mappingDb.getGlobalId(
-                        entity.id
-                    );
-                    globalId = globalId ?? "";
-
-                    if (this.adapter.lockedIds.includes(globalId)) {
-                        console.log("locked skipping ", globalId);
-                        return;
-                    }
-
-                    console.log(
-                        "sending packet for global Id",
-                        globalId,
-                        entity.id
-                    );
-                    const envelope = await this.adapter.handleChange({
-                        data,
-                        tableName: tableName.toLowerCase(),
-                    });
-                } finally {
-                    // Always remove the pending change flag
-                    this.pendingChanges.delete(changeKey);
-                }
-            }, 3_000);
-        } catch (error) {
-            console.error(`Error processing change for ${tableName}:`, error);
-            // Remove the pending change flag on error
-            this.pendingChanges.delete(changeKey);
-        }
+        setTimeout(async () => {
+            try {
+                let globalId = await this.adapter.mappingDb.getGlobalId(
+                    entity.id
+                );
+                globalId = globalId ?? "";
+
+                if (this.adapter.lockedIds.includes(globalId)) {
+                    console.log("locked skipping ", globalId);
+                    return;
+                }
+
+                console.log(
+                    "sending packet for global Id",
+                    globalId,
+                    entity.id
+                );
+                const envelope = await this.adapter.handleChange({
+                    data,
+                    tableName: tableName.toLowerCase(),
+                });
+            } catch (error) {
+                console.error(`Error processing change for ${tableName}:`, error);
+            } finally {
+                // Always remove the pending change flag
+                this.pendingChanges.delete(changeKey);
+            }
+        }, 3_000);

276-303: Fix async error handling in setTimeout callback.

Same issue as in handleChange: the try-catch structure doesn't properly handle async errors within the setTimeout callback.

Apply this pattern:

-            try {
-                setTimeout(async () => {
-                    try {
-                        let globalId = await this.adapter.mappingDb.getGlobalId(
-                            entity.id
-                        );
-                        globalId = globalId ?? "";
-
-                        if (this.adapter.lockedIds.includes(globalId)) {
-                            console.log("locked skipping ", globalId);
-                            return;
-                        }
-
-                        console.log(
-                            "sending packet for global Id",
-                            globalId,
-                            entity.id
-                        );
-
-                        const tableName = `${junctionInfo.entity.toLowerCase()}s`;
-                        await this.adapter.handleChange({
-                            data: this.entityToPlain(parentEntity),
-                            tableName,
-                        });
-                    } finally {
-                        // Always remove the pending change flag
-                        this.pendingChanges.delete(changeKey);
-                    }
-                }, 3_000);
-            } catch (error) {
-                console.error(error);
-                // Remove the pending change flag on error
-                this.pendingChanges.delete(changeKey);
-            }
+            setTimeout(async () => {
+                try {
+                    let globalId = await this.adapter.mappingDb.getGlobalId(
+                        entity.id
+                    );
+                    globalId = globalId ?? "";
+
+                    if (this.adapter.lockedIds.includes(globalId)) {
+                        console.log("locked skipping ", globalId);
+                        return;
+                    }
+
+                    console.log(
+                        "sending packet for global Id",
+                        globalId,
+                        entity.id
+                    );
+
+                    const tableName = `${junctionInfo.entity.toLowerCase()}s`;
+                    await this.adapter.handleChange({
+                        data: this.entityToPlain(parentEntity),
+                        tableName,
+                    });
+                } catch (error) {
+                    console.error(error);
+                } finally {
+                    // Always remove the pending change flag
+                    this.pendingChanges.delete(changeKey);
+                }
+            }, 3_000);
🧹 Nitpick comments (18)
platforms/dreamSync/vite.config.ts (1)

6-7: Path calculation is correct; consider removing the debug log.

The envDir path correctly resolves to the project root (two directories up from platforms/dreamSync/), which is appropriate for loading environment files in a monorepo structure. However, the console.log statement will execute every time the Vite config is loaded, which could be verbose.

If the logging is no longer needed for debugging, consider removing it:

 const envDir = path.resolve(import.meta.dirname, "../../");
-console.log("🔍 Vite envDir:", envDir);
platforms/dreamSync/client/src/lib/utils/mobile-detection.ts (1)

34-50: Eliminate duplicate user agent detection logic.

The user agent detection code here duplicates the logic from isMobileDevice() (lines 7-13). This creates maintenance burden if detection patterns need updating.

Consider refactoring to reuse the existing detection:

 export function getAppStoreLink(): string {
-  if (typeof window === 'undefined') {
+  if (typeof window === 'undefined' || /android/i.test(navigator.userAgent || navigator.vendor)) {
     return "https://play.google.com/store/apps/details?id=foundation.metastate.eid_wallet";
   }
   
-  const userAgent = navigator.userAgent || navigator.vendor || (window as any).opera;
-  
-  if (/android/i.test(userAgent)) {
-    return "https://play.google.com/store/apps/details?id=foundation.metastate.eid_wallet";
-  }
-  
-  if (/iPad|iPhone|iPod/.test(userAgent) && !(window as any).MSStream) {
+  if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !(window as any).MSStream) {
     return "https://apps.apple.com/in/app/eid-for-w3ds/id6747748667";
   }
   
   return "https://play.google.com/store/apps/details?id=foundation.metastate.eid_wallet";
 }

</review_comment_end>

platforms/dreamsync-api/src/database/migrations/1760045198484-migration.ts (2)

7-7: Add unique constraint on email and consider indexing frequently queried fields.

The email field allows duplicates, which could cause authentication and user identity issues. Additionally, commonly queried fields like handle, email, and ename lack indices, which may impact query performance.

Apply these changes:

  1. Add a unique constraint on email:
await queryRunner.query(`CREATE UNIQUE INDEX "IDX_users_email" ON "users" ("email") WHERE "email" IS NOT NULL`);
  1. Add indices on frequently queried fields:
await queryRunner.query(`CREATE INDEX "IDX_users_handle" ON "users" ("handle") WHERE "handle" IS NOT NULL`);
await queryRunner.query(`CREATE INDEX "IDX_users_ename" ON "users" ("ename") WHERE "ename" IS NOT NULL`);
  1. Similarly, consider adding indices on group.name and group.ename for better query performance.

Don't forget to update the down migration to drop these indices.


8-8: Add missing foreign keys and clarify voteId usage

  • No votes table or FK on messages.voteId found—either create a votes table and add FOREIGN KEY("voteId") REFERENCES votes(id) with appropriate ON DELETE action, or drop the voteId column if unused.
  • Add FK constraints on senderId and groupId in this migration, using ON DELETE CASCADE or SET NULL per your retention policy.
platforms/dreamSync/client/src/components/wysiwyg-editor.tsx (3)

21-29: Add error handling to the HTML-to-Markdown conversion.

If turndown encounters malformed HTML or throws an error, the function will crash without graceful degradation.

Apply this diff:

 function htmlToMarkdown(html: string): string {
+  try {
     const turndownService = new TurndownService({
       headingStyle: 'atx',
       bulletListMarker: '-',
       codeBlockStyle: 'fenced',
     })
     
     return turndownService.turndown(html)
+  } catch (error) {
+    console.error('Failed to convert HTML to Markdown:', error)
+    return html // Fallback to returning the HTML
+  }
 }

46-50: Consider debouncing the onChange callback to improve performance.

The onChange callback fires on every keystroke, which triggers Markdown conversion and parent component updates. For large documents, this can cause performance issues.

Consider using a debounced version of onChange or moving the conversion to a separate save action:

import { useMemo } from 'react';
import debounce from 'lodash.debounce';

export default function WysiwygEditor({ content, onChange, placeholder = "Enter text...", className }: WysiwygEditorProps) {
  const debouncedOnChange = useMemo(
    () => debounce((markdown: string) => onChange(markdown), 300),
    [onChange]
  );

  const editor = useEditor({
    // ... extensions
    onUpdate: ({ editor }) => {
      const html = editor.getHTML();
      const markdown = htmlToMarkdown(html);
      debouncedOnChange(markdown);
    },
    // ... rest
  });
  
  // ...
}

10-11: Remove redundant async: false configuration for marked.

marked is synchronous by default, so marked.use({ async: false }) can be removed.

platforms/dreamSync/client/src/components/auth/login-screen.tsx (1)

38-61: Add timeout and reconnection logic for the SSE connection.

The EventSource connection has no timeout, which means users could wait indefinitely if the server doesn't respond. Additionally, there's no automatic reconnection on network errors.

Apply this diff:

   useEffect(() => {
     if (!sessionId) return;
+    
+    let timeoutId: NodeJS.Timeout | null = null;
 
     const eventSource = new EventSource(
       `${import.meta.env.VITE_DREAMSYNC_BASE_URL || "http://localhost:8888"}/api/auth/sessions/${sessionId}`
     );
+    
+    // Set a timeout for the authentication
+    timeoutId = setTimeout(() => {
+      eventSource.close();
+      console.error("Authentication timeout");
+      // Optionally show user feedback here
+    }, 60000); // 60 second timeout
 
     eventSource.onmessage = (event) => {
       try {
         const data = JSON.parse(event.data);
         if (data.user && data.token) {
+          if (timeoutId) clearTimeout(timeoutId);
           setIsConnecting(true);
           localStorage.setItem("dreamsync_token", data.token);
           localStorage.setItem("dreamsync_user_id", data.user.id);
           window.location.href = "/";
         }
       } catch (error) {
         console.error("Error parsing SSE data:", error);
       }
     };
 
     eventSource.onerror = (error) => {
       console.error("SSE Error:", error);
+      if (timeoutId) clearTimeout(timeoutId);
       eventSource.close();
     };
 
     return () => {
+      if (timeoutId) clearTimeout(timeoutId);
       eventSource.close();
     };
   }, [sessionId, login]);
platforms/dreamSync/client/src/lib/auth-context.tsx (2)

59-71: Add input validation and loading state for the login function.

The login function doesn't validate the ename parameter or provide loading state, which could lead to poor UX and unexpected errors.

Apply this diff:

+  const [isLoggingIn, setIsLoggingIn] = useState(false);
+
   const login = async (ename: string) => {
+    if (!ename || ename.trim() === "") {
+      throw new Error("ename is required");
+    }
+    
+    setIsLoggingIn(true);
     try {
       const response = await apiClient.post("/api/auth", { ename });
       const { token, user: userData } = response.data;
       
       setAuthToken(token);
       setAuthId(userData.id);
       setUser(userData);
     } catch (error) {
       console.error("Login failed:", error);
       throw error;
+    } finally {
+      setIsLoggingIn(false);
     }
   };

Then expose isLoggingIn in the context:

 interface AuthContextType {
   user: User | null;
   isAuthenticated: boolean;
   isLoading: boolean;
+  isLoggingIn: boolean;
   login: (ename: string) => Promise<void>;
   logout: () => void;
 }

73-76: Consider adding server-side session invalidation.

The logout function only clears client-side state but doesn't notify the server to invalidate the session. This means the token remains valid until it expires naturally.

If your backend supports session invalidation, consider calling a logout endpoint:

const logout = async () => {
  try {
    await apiClient.post("/api/auth/logout");
  } catch (error) {
    console.error("Server logout failed:", error);
    // Continue with client-side logout even if server call fails
  } finally {
    clearAuth();
    setUser(null);
  }
};

Note: This would require making logout async and updating all consumers.

platforms/dreamSync/client/src/lib/apiClient.ts (2)

12-17: Add timeout configuration to prevent hanging requests.

The API client lacks a timeout configuration, which can cause requests to hang indefinitely if the server is unresponsive. This degrades user experience and can exhaust connection pools.

Apply this diff to add a reasonable timeout:

 export const apiClient = axios.create({
     baseURL,
+    timeout: 30000, // 30 seconds
     headers: {
         "Content-Type": "application/json",
     },
 });

34-44: Consider using router-based navigation instead of window.location.href.

Using window.location.href for navigation causes a full page reload, which disrupts the SPA experience and loses application state. Consider injecting a router-based navigation function or emitting an event that the auth context can handle.

For a cleaner architecture, you could:

  1. Create a custom event that the AuthProvider listens for
  2. Have the AuthProvider handle the logout logic and navigation
  3. Dispatch that event from the interceptor

Example approach:

// In interceptor
if (error.response?.status === 401) {
    localStorage.removeItem("dreamsync_token");
    localStorage.removeItem("dreamsync_user_id");
    window.dispatchEvent(new CustomEvent('auth:unauthorized'));
}

Then in your AuthProvider, listen for this event and use proper router navigation.

Alternatively, if you prefer to keep the current approach for simplicity, the existing implementation is functional but less optimal for SPA patterns.

platforms/dreamSync/client/src/pages/wishlist-editor.tsx (3)

47-84: Consider making title editable and adding privacy control.

The wishlist title is hardcoded to "My Dream Wishlist" and isPublic is always true. This limits user control over their wishlist. Consider adding UI controls for these fields.

You could add state for title and privacy:

const [wishlistTitle, setWishlistTitle] = useState("My Dream Wishlist");
const [isPublic, setIsPublic] = useState(true);

Then add input fields in the UI and use these values in the save handler:

         response = await apiClient.put(`/api/wishlists/${existingWishlist.id}`, {
-          title: "My Dream Wishlist",
+          title: wishlistTitle,
           content: wishlistContent,
-          isPublic: true
+          isPublic: isPublic
         });

This provides users with more flexibility in managing their wishlists.


74-74: Use unknown instead of any for error type.

TypeScript best practices recommend using unknown for caught errors and narrowing the type as needed. This provides better type safety.

Apply this diff:

-    } catch (error: any) {
+    } catch (error: unknown) {
       console.error("Error saving wishlist:", error);

26-45: Remove sorting concern – server orders by updatedAt DESC; add user-facing error toast.

The backend’s WishlistService.getUserWishlists uses order: { updatedAt: "DESC" }, so response.data[0] is already the latest wishlist. Enhance the catch block to notify users on failure:

       } catch (error) {
         console.error("Error loading existing wishlist:", error);
+        toast({
+          title: "Error loading wishlist",
+          description: "Unable to fetch your wishlist. Please try again.",
+          variant: "destructive",
+        });
       } finally {
platforms/dreamsync-api/src/database/migrations/1760422131457-migration.ts (1)

7-7: Consider using jsonb instead of json for PostgreSQL.

The migration adds a json column type. If this is PostgreSQL (which appears likely given the broader codebase context), consider using jsonb instead for better performance and indexing capabilities. The jsonb type is more efficient for queries and supports indexing, while json stores data as plain text.

If using PostgreSQL, apply this diff:

-        await queryRunner.query(`ALTER TABLE "group" ADD "originalMatchParticipants" json`);
+        await queryRunner.query(`ALTER TABLE "group" ADD "originalMatchParticipants" jsonb`);

And update the down migration:

         await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "originalMatchParticipants"`);

Note: Also update the corresponding entity definition in Group.ts from type: "json" to type: "jsonb" for consistency.

platforms/dreamsync-api/src/database/entities/User.ts (1)

64-65: Add missing definite assignment assertion for consistency.

The wishlists relation is missing the definite assignment assertion (!) that's used on other required relations throughout the entity. While this will still work at runtime, it creates inconsistency with the rest of the entity's property declarations.

Apply this diff for consistency:

     @OneToMany(() => Wishlist, (wishlist) => wishlist.user)
-    wishlists: Wishlist[];
+    wishlists!: Wishlist[];
platforms/dreamsync-api/src/controllers/UserController.ts (1)

50-64: Leverage the database search instead of fetching every user

search currently loads the entire user table into memory and filters it in Node. That will thrash memory and degrade latency once the user base grows, and it ignores any DB-level filtering we already wrote in UserService.searchUsers. Please delegate the query to the service so the database does the heavy lifting:

-            const users = await this.userService.getAllUsers();
-            const filteredUsers = users.filter(user => 
-                user.name?.toLowerCase().includes(q.toLowerCase()) ||
-                user.handle?.toLowerCase().includes(q.toLowerCase()) ||
-                user.ename?.toLowerCase().includes(q.toLowerCase())
-            );
-
-            res.json(filteredUsers.map(user => ({
+            const users = await this.userService.searchUsers(q);
+
+            res.json(users.map(user => ({
                 id: user.id,
                 ename: user.ename,
                 name: user.name,
                 handle: user.handle,
                 avatarUrl: user.avatarUrl,
                 isVerified: user.isVerified,
             })));
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c3e3b19 and 8256603.

⛔ Files ignored due to path filters (5)
  • infrastructure/eid-wallet/src-tauri/gen/apple/eid-wallet.xcodeproj/project.pbxproj is excluded by !**/gen/**
  • infrastructure/eid-wallet/src-tauri/gen/apple/eid-wallet_iOS/Info.plist is excluded by !**/gen/**
  • platforms/dreamSync/client/public/W3DS.svg is excluded by !**/*.svg
  • platforms/dreamSync/package-lock.json is excluded by !**/package-lock.json
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (94)
  • infrastructure/eVoting/src/components/signing-interface.tsx (0 hunks)
  • infrastructure/eid-wallet/src/routes/(app)/scan-qr/+page.svelte (6 hunks)
  • platforms/blabsy-w3ds-auth-api/src/controllers/AuthController.ts (1 hunks)
  • platforms/blabsy-w3ds-auth-api/src/controllers/WebhookController.ts (3 hunks)
  • platforms/dreamSync/client/src/App.tsx (3 hunks)
  • platforms/dreamSync/client/src/components/auth/login-screen.tsx (1 hunks)
  • platforms/dreamSync/client/src/components/auth/protected-route.tsx (1 hunks)
  • platforms/dreamSync/client/src/components/wysiwyg-editor.tsx (1 hunks)
  • platforms/dreamSync/client/src/hooks/useAuth.ts (1 hunks)
  • platforms/dreamSync/client/src/lib/apiClient.ts (1 hunks)
  • platforms/dreamSync/client/src/lib/auth-context.tsx (1 hunks)
  • platforms/dreamSync/client/src/lib/authUtils.ts (1 hunks)
  • platforms/dreamSync/client/src/lib/utils/mobile-detection.ts (1 hunks)
  • platforms/dreamSync/client/src/pages/dashboard.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/groups.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/login.tsx (1 hunks)
  • platforms/dreamSync/client/src/pages/matches-new.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/profile.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/suggestions.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/wishlist-editor.tsx (1 hunks)
  • platforms/dreamSync/client/src/pages/wishlist-item.tsx (0 hunks)
  • platforms/dreamSync/client/src/pages/wishlist.tsx (0 hunks)
  • platforms/dreamSync/package.json (1 hunks)
  • platforms/dreamSync/server/aiSuggestionsService.ts (0 hunks)
  • platforms/dreamSync/server/auth.ts (0 hunks)
  • platforms/dreamSync/server/db.ts (0 hunks)
  • platforms/dreamSync/server/ensureFullyPopulatedData.ts (0 hunks)
  • platforms/dreamSync/server/fixPasswords.ts (0 hunks)
  • platforms/dreamSync/server/generateTestSuggestions.ts (0 hunks)
  • platforms/dreamSync/server/index.ts (0 hunks)
  • platforms/dreamSync/server/openai.ts (0 hunks)
  • platforms/dreamSync/server/replitAuth.ts (0 hunks)
  • platforms/dreamSync/server/routes.ts (0 hunks)
  • platforms/dreamSync/server/seedComprehensiveData.ts (0 hunks)
  • platforms/dreamSync/server/seedData.ts (0 hunks)
  • platforms/dreamSync/server/seedEnhancedData.ts (0 hunks)
  • platforms/dreamSync/server/seedExtensiveData.ts (0 hunks)
  • platforms/dreamSync/server/storage.ts (0 hunks)
  • platforms/dreamSync/server/vite.ts (0 hunks)
  • platforms/dreamSync/vite.config.ts (2 hunks)
  • platforms/dreamsync-api/README.md (1 hunks)
  • platforms/dreamsync-api/package.json (1 hunks)
  • platforms/dreamsync-api/reset.sh (1 hunks)
  • platforms/dreamsync-api/src/auth.ts (1 hunks)
  • platforms/dreamsync-api/src/controllers/AuthController.ts (1 hunks)
  • platforms/dreamsync-api/src/controllers/MatchController.ts (1 hunks)
  • platforms/dreamsync-api/src/controllers/UserController.ts (1 hunks)
  • platforms/dreamsync-api/src/controllers/WebhookController.ts (1 hunks)
  • platforms/dreamsync-api/src/controllers/WishlistController.ts (1 hunks)
  • platforms/dreamsync-api/src/database/data-source.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/Group.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/Match.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/Message.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/User.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/UserEVaultMapping.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/WebhookProcessing.ts (1 hunks)
  • platforms/dreamsync-api/src/database/entities/Wishlist.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760045198484-migration.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760080210824-migration.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760087325046-AddUserEVaultMapping.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760087896024-AddMatchConsentFields.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760422131457-migration.ts (1 hunks)
  • platforms/dreamsync-api/src/database/migrations/1760427215447-migration.ts (1 hunks)
  • platforms/dreamsync-api/src/index.ts (1 hunks)
  • platforms/dreamsync-api/src/middleware/auth.ts (1 hunks)
  • platforms/dreamsync-api/src/services/AIMatchingService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/ConsentService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/GroupService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/MatchNotificationService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/MatchingJob.ts (1 hunks)
  • platforms/dreamsync-api/src/services/MatchingService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/MessageService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/PlatformEVaultService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/SharedMatchingService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/UserService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/WebhookProcessingService.ts (1 hunks)
  • platforms/dreamsync-api/src/services/WishlistService.ts (1 hunks)
  • platforms/dreamsync-api/src/types/express.d.ts (1 hunks)
  • platforms/dreamsync-api/src/utils/jwt.ts (1 hunks)
  • platforms/dreamsync-api/src/utils/typeorm-adapter.ts (1 hunks)
  • platforms/dreamsync-api/src/web3adapter/index.ts (1 hunks)
  • platforms/dreamsync-api/src/web3adapter/mappings/group.mapping.json (1 hunks)
  • platforms/dreamsync-api/src/web3adapter/mappings/message.mapping.json (1 hunks)
  • platforms/dreamsync-api/src/web3adapter/mappings/user.mapping.json (1 hunks)
  • platforms/dreamsync-api/src/web3adapter/watchers/subscriber.ts (1 hunks)
  • platforms/dreamsync-api/test-matchmaking-mock.ts (1 hunks)
  • platforms/dreamsync-api/test-matchmaking.ts (1 hunks)
  • platforms/dreamsync-api/tsconfig.json (1 hunks)
  • platforms/marketplace/package.json (1 hunks)
  • platforms/pictique-api/package.json (1 hunks)
  • platforms/pictique-api/src/controllers/WebhookController.ts (1 hunks)
  • platforms/pictique-api/src/web3adapter/mappings/chat.mapping.json (1 hunks)
  • platforms/pictique-api/src/web3adapter/watchers/subscriber.ts (1 hunks)
  • platforms/registry/src/index.ts (1 hunks)
💤 Files with no reviewable changes (24)
  • platforms/dreamSync/client/src/pages/groups.tsx
  • platforms/dreamSync/server/fixPasswords.ts
  • platforms/dreamSync/client/src/pages/wishlist.tsx
  • platforms/dreamSync/server/seedComprehensiveData.ts
  • platforms/dreamSync/server/replitAuth.ts
  • platforms/dreamSync/client/src/pages/matches-new.tsx
  • platforms/dreamSync/client/src/pages/profile.tsx
  • platforms/dreamSync/client/src/pages/wishlist-item.tsx
  • platforms/dreamSync/server/routes.ts
  • platforms/dreamSync/server/generateTestSuggestions.ts
  • platforms/dreamSync/server/seedEnhancedData.ts
  • platforms/dreamSync/server/ensureFullyPopulatedData.ts
  • platforms/dreamSync/server/storage.ts
  • platforms/dreamSync/server/seedExtensiveData.ts
  • platforms/dreamSync/server/index.ts
  • platforms/dreamSync/server/seedData.ts
  • platforms/dreamSync/server/openai.ts
  • platforms/dreamSync/server/vite.ts
  • platforms/dreamSync/client/src/pages/dashboard.tsx
  • platforms/dreamSync/server/db.ts
  • infrastructure/eVoting/src/components/signing-interface.tsx
  • platforms/dreamSync/server/aiSuggestionsService.ts
  • platforms/dreamSync/client/src/pages/suggestions.tsx
  • platforms/dreamSync/server/auth.ts
🧰 Additional context used
🧬 Code graph analysis (34)
platforms/dreamSync/client/src/lib/auth-context.tsx (1)
platforms/dreamSync/client/src/lib/apiClient.ts (1)
  • apiClient (12-17)
platforms/dreamsync-api/src/database/entities/Group.ts (3)
platforms/dreamsync-api/src/database/entities/Match.ts (1)
  • Entity (26-105)
platforms/dreamsync-api/src/database/entities/User.ts (1)
  • Entity (13-75)
platforms/dreamsync-api/src/database/entities/Message.ts (1)
  • Entity (12-40)
platforms/dreamsync-api/src/services/UserService.ts (1)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
platforms/dreamsync-api/src/database/entities/User.ts (4)
platforms/dreamsync-api/src/database/entities/Group.ts (1)
  • Entity (14-81)
platforms/dreamsync-api/src/database/entities/Match.ts (1)
  • Entity (26-105)
platforms/dreamsync-api/src/database/entities/Wishlist.ts (1)
  • Entity (14-54)
platforms/dreamsync-api/src/database/entities/Message.ts (1)
  • Entity (12-40)
platforms/dreamsync-api/src/database/entities/Match.ts (2)
platforms/dreamsync-api/src/database/entities/User.ts (1)
  • Entity (13-75)
platforms/dreamsync-api/src/database/entities/Wishlist.ts (1)
  • Entity (14-54)
platforms/dreamsync-api/src/services/ConsentService.ts (2)
platforms/dreamsync-api/src/services/GroupService.ts (1)
  • GroupService (6-239)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
platforms/dreamsync-api/src/database/data-source.ts (1)
infrastructure/web3-adapter/src/logging/transport.js (1)
  • envPath (10-10)
platforms/dreamsync-api/src/services/WebhookProcessingService.ts (1)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
platforms/dreamsync-api/src/auth.ts (2)
platforms/dreamsync-api/src/utils/typeorm-adapter.ts (1)
  • typeormAdapter (4-6)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
platforms/dreamsync-api/src/database/entities/Message.ts (2)
platforms/dreamsync-api/src/database/entities/Group.ts (1)
  • Entity (14-81)
platforms/dreamsync-api/src/database/entities/User.ts (1)
  • Entity (13-75)
platforms/dreamSync/client/src/pages/wishlist-editor.tsx (3)
platforms/dreamSync/client/src/lib/auth-context.tsx (1)
  • useAuth (85-91)
platforms/dreamSync/client/src/lib/apiClient.ts (1)
  • apiClient (12-17)
platforms/dreamSync/client/src/components/wysiwyg-editor.tsx (1)
  • WysiwygEditor (37-197)
platforms/dreamsync-api/test-matchmaking.ts (1)
platforms/dreamsync-api/src/services/AIMatchingService.ts (1)
  • AIMatchingService (10-700)
platforms/dreamsync-api/src/services/MatchNotificationService.ts (3)
platforms/dreamsync-api/src/services/UserService.ts (1)
  • UserService (4-69)
platforms/dreamsync-api/src/services/GroupService.ts (1)
  • GroupService (6-239)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
platforms/dreamsync-api/src/database/entities/Wishlist.ts (2)
platforms/dreamsync-api/src/database/entities/Match.ts (1)
  • Entity (26-105)
platforms/dreamsync-api/src/database/entities/User.ts (1)
  • Entity (13-75)
platforms/dreamsync-api/src/web3adapter/watchers/subscriber.ts (4)
platforms/blabsy-w3ds-auth-api/src/controllers/WebhookController.ts (1)
  • adapter (73-78)
platforms/pictique-api/src/web3adapter/watchers/subscriber.ts (1)
  • adapter (17-22)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
platforms/evoting-api/src/web3adapter/watchers/subscriber.ts (1)
  • PostgresSubscriber (30-468)
platforms/dreamsync-api/src/middleware/auth.ts (2)
platforms/dreamsync-api/src/utils/jwt.ts (1)
  • verifyToken (9-11)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
platforms/dreamsync-api/src/services/MatchingService.ts (1)
platforms/dreamsync-api/src/services/SharedMatchingService.ts (3)
  • MatchResult (3-11)
  • WishlistData (13-22)
  • MatchingService (24-176)
platforms/dreamsync-api/src/index.ts (9)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
platforms/dreamsync-api/src/services/PlatformEVaultService.ts (1)
  • PlatformEVaultService (41-313)
platforms/dreamsync-api/src/services/MatchingJob.ts (1)
  • MatchingJob (3-75)
platforms/dreamsync-api/src/controllers/UserController.ts (1)
  • UserController (4-131)
platforms/dreamsync-api/src/controllers/AuthController.ts (1)
  • AuthController (7-104)
platforms/dreamsync-api/src/controllers/WebhookController.ts (1)
  • WebhookController (13-360)
platforms/dreamsync-api/src/controllers/WishlistController.ts (1)
  • WishlistController (4-131)
platforms/dreamsync-api/src/controllers/MatchController.ts (1)
  • MatchController (5-99)
platforms/dreamsync-api/src/middleware/auth.ts (2)
  • authMiddleware (6-38)
  • authGuard (40-45)
platforms/dreamsync-api/src/services/GroupService.ts (1)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
platforms/dreamsync-api/test-matchmaking-mock.ts (1)
platforms/dreamsync-api/src/services/MatchingService.ts (3)
  • MatchingService (36-280)
  • WishlistData (15-24)
  • MatchResult (3-13)
platforms/dreamSync/client/src/components/auth/protected-route.tsx (2)
platforms/dreamSync/client/src/lib/auth-context.tsx (1)
  • useAuth (85-91)
platforms/dreamSync/client/src/components/auth/login-screen.tsx (1)
  • LoginScreen (8-163)
platforms/dreamsync-api/src/services/SharedMatchingService.ts (1)
platforms/dreamsync-api/src/services/MatchingService.ts (3)
  • MatchResult (3-13)
  • WishlistData (15-24)
  • MatchingService (36-280)
platforms/dreamsync-api/src/services/PlatformEVaultService.ts (3)
platforms/dreamsync-api/src/index.ts (1)
  • PlatformEVaultService (129-129)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
infrastructure/web3-adapter/src/index.js (5)
  • registryEntropy (62-62)
  • now (118-118)
  • attempt (131-131)
  • client (137-137)
  • delay (167-167)
platforms/dreamsync-api/src/services/WishlistService.ts (1)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
platforms/dreamsync-api/src/services/AIMatchingService.ts (3)
platforms/dreamsync-api/src/services/MatchingService.ts (4)
  • MatchingService (36-280)
  • WishlistData (15-24)
  • GroupData (26-34)
  • MatchResult (3-13)
platforms/dreamsync-api/src/services/MatchNotificationService.ts (1)
  • MatchNotificationService (10-1061)
platforms/dreamsync-api/src/database/data-source.ts (1)
  • AppDataSource (29-29)
platforms/dreamsync-api/src/services/MatchingJob.ts (1)
platforms/dreamsync-api/src/services/AIMatchingService.ts (1)
  • AIMatchingService (10-700)
platforms/dreamsync-api/src/controllers/WebhookController.ts (4)
platforms/dreamsync-api/src/services/GroupService.ts (1)
  • GroupService (6-239)
platforms/dreamsync-api/src/services/ConsentService.ts (1)
  • ConsentService (9-1604)
platforms/dreamsync-api/src/services/WebhookProcessingService.ts (1)
  • WebhookProcessingService (6-140)
platforms/dreamsync-api/src/web3adapter/watchers/subscriber.ts (1)
  • adapter (15-20)
platforms/dreamsync-api/src/database/entities/UserEVaultMapping.ts (1)
platforms/dreamsync-api/src/database/entities/Match.ts (1)
  • Entity (26-105)
platforms/dreamSync/client/src/components/auth/login-screen.tsx (3)
platforms/dreamSync/client/src/lib/auth-context.tsx (1)
  • useAuth (85-91)
platforms/dreamSync/client/src/lib/apiClient.ts (1)
  • apiClient (12-17)
platforms/dreamSync/client/src/lib/utils/mobile-detection.ts (3)
  • getAppStoreLink (34-50)
  • isMobileDevice (1-26)
  • getDeepLinkUrl (28-32)
platforms/dreamsync-api/src/controllers/UserController.ts (1)
platforms/dreamsync-api/src/services/UserService.ts (1)
  • UserService (4-69)
platforms/dreamsync-api/src/controllers/AuthController.ts (3)
platforms/blabsy-w3ds-auth-api/src/controllers/AuthController.ts (1)
  • AuthController (5-71)
platforms/dreamsync-api/src/services/UserService.ts (1)
  • UserService (4-69)
platforms/dreamsync-api/src/utils/jwt.ts (1)
  • signToken (5-7)
platforms/dreamsync-api/src/controllers/WishlistController.ts (1)
platforms/dreamsync-api/src/services/WishlistService.ts (1)
  • WishlistService (6-131)
platforms/dreamSync/client/src/App.tsx (2)
platforms/dreamSync/client/src/pages/wishlist-editor.tsx (1)
  • WishlistEditor (17-187)
platforms/dreamSync/client/src/lib/auth-context.tsx (1)
  • AuthProvider (33-83)
platforms/dreamsync-api/src/controllers/MatchController.ts (1)
platforms/dreamsync-api/src/services/AIMatchingService.ts (1)
  • AIMatchingService (10-700)
🪛 ast-grep (0.39.6)
platforms/dreamsync-api/src/services/MatchNotificationService.ts

[warning] 429-429: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(\\{${userADisplayName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\}, 'g')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 435-435: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(\\{${userADisplayName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\}, 'g')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 443-443: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(\\{${userBDisplayName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\}, 'g')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 449-449: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(\\{${userBDisplayName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\}, 'g')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🪛 LanguageTool
platforms/dreamsync-api/README.md

[grammar] ~3-~3: There might be a mistake here.
Context: ...mSync platform, cloned from evoting-api with focus on user management, groups, and m...

(QB_NEW_EN)


[grammar] ~7-~7: There might be a mistake here.
Context: ...rofiles, authentication, and user search - Group Management: Group creation, memb...

(QB_NEW_EN)


[grammar] ~8-~8: There might be a mistake here.
Context: ...creation, membership, and administration - Messaging: Group messaging with system...

(QB_NEW_EN)


[grammar] ~9-~9: There might be a mistake here.
Context: ...up messaging with system message support - Web3 Integration: Web3Adapter integrat...

(QB_NEW_EN)


[grammar] ~10-~10: There might be a mistake here.
Context: ...n for decentralized data synchronization - Authentication: JWT-based authenticati...

(QB_NEW_EN)


[grammar] ~17-~17: There might be a mistake here.
Context: ...s with followers/following relationships - Group: Groups with members, admins, an...

(QB_NEW_EN)


[grammar] ~18-~18: There might be a mistake here.
Context: ...s with members, admins, and participants - Message: Messages within groups, inclu...

(QB_NEW_EN)


[grammar] ~94-~94: There might be a mistake here.
Context: ...ration for: - User data synchronization - Message synchronization (system messages...

(QB_NEW_EN)


[grammar] ~95-~95: There might be a mistake here.
Context: ...e synchronization (system messages only) - Group data synchronization ## Differenc...

(QB_NEW_EN)


[grammar] ~102-~102: There might be a mistake here.
Context: ...uses on: - User management and profiles - Group functionality - Basic messaging - ...

(QB_NEW_EN)


[grammar] ~103-~103: There might be a mistake here.
Context: ...ement and profiles - Group functionality - Basic messaging - Web3Adapter integratio...

(QB_NEW_EN)


[grammar] ~104-~104: There might be a mistake here.
Context: ... - Group functionality - Basic messaging - Web3Adapter integration for users and me...

(QB_NEW_EN)

🔇 Additional comments (28)
platforms/dreamSync/vite.config.ts (1)

40-40: LGTM! Correctly configures envDir for the monorepo.

Explicitly setting envDir ensures that environment variables are loaded from the project root, which is the correct approach for a monorepo structure where multiple platforms share a common configuration.

platforms/dreamsync-api/src/database/migrations/1760045198484-migration.ts (2)

16-24: Clarify the distinction between group relationship tables.

Three separate many-to-many tables exist for group-user relationships: group_members, group_admins, and group_participants. The semantic difference between "members" and "participants" is unclear.

Verify whether:

  1. All three tables are necessary, or if roles could be consolidated into a single group_members table with a role column
  2. The distinction serves a specific business requirement
  3. Users can exist in multiple tables simultaneously (e.g., can an admin also be a participant?)

This design could lead to data inconsistencies if the relationships aren't mutually exclusive or if the business rules aren't clearly enforced at the application level.


39-70: LGTM: Down migration correctly reverses the up migration.

The down migration properly drops all constraints, indices, and tables in the correct reverse order, ensuring clean rollback.

platforms/registry/src/index.ts (1)

16-21: Review the CORS wildcard configuration.

The CORS configuration allows all origins (origin: "*"). While this may be intentional for a public registry service, ensure this aligns with your security requirements. If the registry handles sensitive operations or tokens, restrict origins to known platforms.

platforms/dreamSync/client/src/pages/login.tsx (1)

1-5: LGTM!

The refactoring to delegate login logic to the LoginScreen component simplifies this file and improves separation of concerns.

platforms/dreamSync/client/src/hooks/useAuth.ts (1)

1-5: LGTM!

Delegating to the centralized auth context improves maintainability and reduces duplication. The public interface remains unchanged.

platforms/dreamSync/client/src/components/auth/protected-route.tsx (1)

11-27: LGTM!

The authentication flow is correctly implemented with proper loading and unauthenticated state handling.

platforms/dreamSync/client/src/App.tsx (2)

44-49: LGTM!

The authentication provider is correctly positioned in the component hierarchy, wrapping all components that need auth state access.


34-34: LGTM!

Simplified routing to focus on the WishlistEditor aligns with the PR objectives.

platforms/dreamSync/client/src/components/auth/login-screen.tsx (1)

48-49: Document the XSS risk of localStorage token storage.

Storing authentication tokens in localStorage makes them vulnerable to XSS attacks. While this is a common pattern, ensure:

  1. Your Content Security Policy (CSP) is strict
  2. All user-generated content is properly sanitized
  3. You use httpOnly cookies for sensitive production environments

Based on learnings from security best practices, consider using httpOnly cookies for token storage in production to mitigate XSS risks.

platforms/dreamSync/client/src/lib/auth-context.tsx (2)

39-57: LGTM!

The initialization logic correctly handles token validation and gracefully clears auth state on errors.


85-91: LGTM!

The useAuth hook properly enforces usage within an AuthProvider with a clear error message.

platforms/dreamSync/client/src/pages/wishlist-editor.tsx (2)

90-101: LGTM!

The loading state provides good visual feedback with an animated spinner and clear messaging. The styling and user experience are well-implemented.


103-186: LGTM! Well-structured UI with good visual hierarchy.

The component UI is well-organized with clear sections, appropriate visual feedback, and helpful tips for users. The conditional rendering based on existingWishlist provides good context.

One minor optional improvement: consider extracting the tips array as a constant for better maintainability:

const WISHLIST_TIPS = [
  "Be specific about what you want and what you can offer",
  "Include both short-term and long-term goals",
  "Don't be afraid to dream big!",
  "Update your wishlist regularly as you grow and change"
];

Then map over it in the render, but this is purely optional for code organization.

platforms/dreamSync/client/src/lib/authUtils.ts (2)

5-16: LGTM! Token management functions are well-implemented.

The token management functions are properly implemented with SSR safety checks in getAuthToken(). The localStorage key dreamsync_token is consistent with the usage in apiClient.ts.


18-34: LGTM! ID management and clearAuth helper are well-implemented.

The user ID management functions follow the same pattern as token management with proper SSR safety. The clearAuth() helper provides a convenient way to clear all authentication data, which is consistent with the logout flow in apiClient.ts.

platforms/dreamsync-api/src/web3adapter/mappings/group.mapping.json (1)

1-24: LGTM! Consistent array mapping syntax.

The mapping definitions use consistent array notation ([].id) for all user collection fields (admins, participants, members), which provides clear and uniform data transformation rules for the web3 adapter.

platforms/dreamsync-api/tsconfig.json (1)

1-23: LGTM! Appropriate TypeScript configuration for TypeORM.

The configuration correctly enables decorator support (experimentalDecorators, emitDecoratorMetadata) required for TypeORM entities, and strictPropertyInitialization: false is a standard practice when using TypeORM's definite assignment assertions.

platforms/dreamsync-api/src/database/entities/WebhookProcessing.ts (1)

1-38: LGTM! Well-designed webhook deduplication entity.

The entity correctly uses a unique index on webhookId (line 4) for idempotent webhook processing, and stores the full payload in jsonb (line 30) for debugging. The status lifecycle (pendingprocessingcompleted/failed) is clear and appropriate.

Consider implementing a cleanup strategy for old completed records to prevent unbounded growth (e.g., a scheduled job to delete records older than 30 days with status completed).

platforms/dreamsync-api/src/database/entities/User.ts (1)

48-62: LGTM! Self-referential many-to-many relations correctly configured.

The followers and following relationships are properly set up with explicit join table configurations, correctly modeling the bidirectional follow relationships.

platforms/dreamsync-api/src/web3adapter/mappings/user.mapping.json (1)

18-19: No transformation syntax needed for followers/following
Subscriber watchers handle user_followers/user_following via ownedJunctionTables and emit updates for the followers and following fields—simple mappings in user.mapping.json are correct.

platforms/dreamsync-api/src/types/express.d.ts (1)

1-9: LGTM!

Standard Express namespace augmentation for attaching authenticated user information to requests. This pattern integrates well with the authentication middleware.

platforms/dreamsync-api/src/web3adapter/index.ts (1)

1-1: LGTM!

Clean barrel export pattern that exposes the adapter at the module level.

platforms/pictique-api/src/web3adapter/watchers/subscriber.ts (1)

9-9: LGTM!

Import path correctly updated to use the public "web3-adapter" package instead of the relative infrastructure path.

platforms/blabsy-w3ds-auth-api/src/controllers/WebhookController.ts (1)

49-49: LGTM!

The admins field is properly integrated into the Chat type and processing logic, with consistent parsing (extracting IDs from parentheses) and safe defaulting via nullish coalescing.

Also applies to: 291-293, 309-309

platforms/dreamsync-api/src/web3adapter/mappings/message.mapping.json (1)

1-15: LGTM!

The mapping configuration follows the web3-adapter schema conventions. Ensure runtime validation confirms that the relationship syntax (e.g., users(sender.id), groups(group.id)) aligns with the adapter's mapping engine expectations.

platforms/dreamsync-api/src/auth.ts (1)

5-11: LGTM!

Standard betterAuth initialization with appropriate configuration for email/password auth and TypeORM adapter integration. The localhost fallback for trustedOrigins is suitable for development.

platforms/dreamsync-api/README.md (1)

1-107: LGTM!

Comprehensive documentation covering features, setup, environment variables, and API endpoints. The static analysis warnings about list formatting are pedantic—the current markdown is widely supported and readable.

Comment on lines +688 to +714
// 🔐 Get the real public key for voter identification using KeyManager
let voterPublicKey: string;
try {
await generate("default");
console.log(
"✅ Default key generated/verified for blind voting",
);
} catch (edit) {
console.log(
"Default key already exists or generation failed:",
edit,
);
}
// Get the appropriate key manager for blind voting
const keyManager =
await KeyManagerFactory.getKeyManagerForContext(
vault.ename,
"signing",
);

// Get the public key
voterPublicKey = await getPublicKey("default");
console.log("🔑 Voter public key retrieved:", voterPublicKey);
} catch (error) {
console.error("Failed to get cryptographic public key:", error);
// Fallback to ename if crypto fails
voterPublicKey = vault.ename || "unknown_public_key";
}
// Ensure the key exists
if (!(await keyManager.exists(vault.ename))) {
await keyManager.generate(vault.ename);
}

// Dynamically import the blindvote library
const { VotingSystem } = await import("blindvote");
// Get the W3ID (public key)
const w3idResult = await keyManager.getPublicKey(vault.ename);
if (!w3idResult) {
throw new Error("Failed to get W3ID");
}
voterPublicKey = w3idResult;

// Use the user's W3ID as the voter ID (strip @ prefix if present)
const voterId = vault.ename?.startsWith("@")
? vault.ename.slice(1)
: vault.ename;
console.log("🔍 DEBUG: Using voter ID:", voterId);
console.log("🔑 Voter W3ID retrieved:", voterPublicKey);
} catch (error) {
console.error("Failed to get W3ID using KeyManager:", error);
// Fallback to ename if KeyManager fails
voterPublicKey = vault.ename || "unknown_public_key";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Use the retrieved W3ID in the blind vote payload

Line 865 still posts vault?.ename even though we just derived the voter’s W3ID via KeyManager. That breaks the new backend contract (and defeats the fallback) because the server keeps receiving the old identifier instead of the signed public key. Please wire the fetched value through.

-                userW3id: vault?.ename || "",
+                userW3id: voterPublicKey,

Also applies to: 861-868

try {
const { ename, session } = req.body;

console.log(req.body)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove debug log that may expose sensitive data.

Logging the entire request body (req.body) can expose sensitive information such as user identifiers (ename) and session tokens in production logs, creating compliance risks (GDPR/CCPA violations) and security vulnerabilities if logs are compromised.

Apply this diff to remove the debug log:

-
-            console.log(req.body)
-
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log(req.body)
🤖 Prompt for AI Agents
In platforms/blabsy-w3ds-auth-api/src/controllers/AuthController.ts around line
56, remove the debug console.log(req.body) which can leak sensitive user/session
data; simply delete that logging statement (or replace it with a non-sensitive,
structured audit log if needed—e.g., log only request ID or sanitized fields)
and ensure no other debug prints of full request bodies remain in the
controller.

Comment on lines +9 to +17
if [ ! -f "../../../.env" ]; then
echo "❌ .env file not found at ../../../.env"
echo "Please create a .env file with the required environment variables"
exit 1
fi

# Load environment variables
source ../../../.env

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Resolve .env path relative to the script.
When this script is invoked from the repo root (e.g., bash platforms/dreamsync-api/reset.sh), the check at Line 9 inspects ../../../.env relative to the current working directory, not the script’s location. That resolves outside the repository, so the check (and subsequent source) fails and the reset exits immediately. Derive the path from the script directory instead.

-# Check if .env file exists
-if [ ! -f "../../../.env" ]; then
+# Resolve paths relative to this script
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+ENV_FILE="${SCRIPT_DIR}/../../../.env"
+
+# Check if .env file exists
+if [ ! -f "${ENV_FILE}" ]; then
     echo "❌ .env file not found at ../../../.env"
     echo "Please create a .env file with the required environment variables"
     exit 1
 fi
 
 # Load environment variables
-source ../../../.env
+source "${ENV_FILE}"

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In platforms/dreamsync-api/reset.sh around lines 9 to 17, the script currently
checks and sources ../../../.env relative to the current working directory which
fails when invoked from elsewhere; change it to compute the script directory
(e.g., DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)") and derive the .env
path from that directory (use the correct relative path from the script
location, e.g. "$DIR/../../.env"), then test -f against that computed path and
source that computed path so the script works regardless of the current working
directory.

Comment on lines +56 to +99
const { ename, session, w3id, signature } = req.body;

if (!ename) {
return res.status(400).json({ error: "ename is required" });
}

if (!session) {
return res.status(400).json({ error: "session is required" });
}

// Only find existing users - don't create new ones during auth
const user = await this.userService.findUser(ename);

if (!user) {
// User doesn't exist - they need to be created via webhook first
return res.status(404).json({
error: "User not found",
message: "User must be created via eVault webhook before authentication"
});
}

const token = signToken({ userId: user.id });

const data = {
user: {
id: user.id,
ename: user.ename,
name: user.name,
handle: user.handle,
description: user.description,
avatarUrl: user.avatarUrl,
bannerUrl: user.bannerUrl,
isVerified: user.isVerified,
isPrivate: user.isPrivate,
email: user.email,
emailVerified: user.emailVerified,
createdAt: user.createdAt,
updatedAt: user.updatedAt,
},
token,
};
this.eventEmitter.emit(session, data);
res.status(200).send();
} catch (error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Login flow issues tokens without authenticating the caller

login only checks that an ename and session string are present. It never verifies the provided w3id/signature, never challenges the caller, and happily signs a JWT for any existing user. An attacker can POST { ename: "victim", session: "xyz" } and immediately obtain a valid token.

We must actually authenticate: validate the signature (or other credential) against the expected challenge, ensure the session belongs to that challenge, and reject the request otherwise. Until that is in place, do not emit tokens.

Comment on lines +104 to +125
const updates = req.body;
const user = await this.userService.updateUser(req.user.id, updates);

if (!user) {
return res.status(404).json({ error: "User not found" });
}

res.json({
id: user.id,
ename: user.ename,
name: user.name,
handle: user.handle,
description: user.description,
avatarUrl: user.avatarUrl,
bannerUrl: user.bannerUrl,
isVerified: user.isVerified,
isPrivate: user.isPrivate,
email: user.email,
emailVerified: user.emailVerified,
createdAt: user.createdAt,
updatedAt: user.updatedAt,
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Do not persist arbitrary request bodies into the user record

req.body is handed straight to UserService.updateUser, which issues a raw repository update with whatever fields the caller supplies. A malicious client can flip privileged flags like isVerified, isPrivate, or emailVerified, overwrite another user’s email, or mutate audit fields. Please whitelist the mutable profile attributes (e.g. name, handle, description, avatarUrl, bannerUrl) and drop everything else before calling the service, or add server-side validation to updateUser so only expected keys make it to the database.

Example fix:

-            const updates = req.body;
-            const user = await this.userService.updateUser(req.user.id, updates);
+            const { name, handle, description, avatarUrl, bannerUrl } = req.body ?? {};
+            const updates = Object.fromEntries(
+                Object.entries({
+                    name,
+                    handle,
+                    description,
+                    avatarUrl,
+                    bannerUrl,
+                }).filter(([, value]) => value !== undefined)
+            );
+
+            if (Object.keys(updates).length === 0) {
+                return res.status(400).json({ error: "No updatable fields provided" });
+            }
+
+            const user = await this.userService.updateUser(req.user.id, updates);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const updates = req.body;
const user = await this.userService.updateUser(req.user.id, updates);
if (!user) {
return res.status(404).json({ error: "User not found" });
}
res.json({
id: user.id,
ename: user.ename,
name: user.name,
handle: user.handle,
description: user.description,
avatarUrl: user.avatarUrl,
bannerUrl: user.bannerUrl,
isVerified: user.isVerified,
isPrivate: user.isPrivate,
email: user.email,
emailVerified: user.emailVerified,
createdAt: user.createdAt,
updatedAt: user.updatedAt,
});
// only allow updating these profile fields
const { name, handle, description, avatarUrl, bannerUrl } = req.body ?? {};
const updates = Object.fromEntries(
Object.entries({
name,
handle,
description,
avatarUrl,
bannerUrl,
}).filter(([, value]) => value !== undefined)
);
if (Object.keys(updates).length === 0) {
return res.status(400).json({ error: "No updatable fields provided" });
}
const user = await this.userService.updateUser(req.user.id, updates);
if (!user) {
return res.status(404).json({ error: "User not found" });
}
res.json({
id: user.id,
ename: user.ename,
name: user.name,
handle: user.handle,
description: user.description,
avatarUrl: user.avatarUrl,
bannerUrl: user.bannerUrl,
isVerified: user.isVerified,
isPrivate: user.isPrivate,
email: user.email,
emailVerified: user.emailVerified,
createdAt: user.createdAt,
updatedAt: user.updatedAt,
});
🤖 Prompt for AI Agents
In platforms/dreamsync-api/src/controllers/UserController.ts around lines 104 to
125, the controller currently passes req.body straight to updateUser which
allows clients to persist arbitrary fields (including privileged flags and audit
fields). Replace that by whitelisting allowed updatable profile attributes (e.g.
name, handle, description, avatarUrl, bannerUrl) and building a new updates
object from req.body that only copies those keys (with type
checks/normalization), explicitly ignore/omit fields like id, email, isVerified,
isPrivate, emailVerified, createdAt, updatedAt, and any other server-controlled
properties, then call this.userService.updateUser(req.user.id, filteredUpdates);
alternatively, add server-side validation in UserService.updateUser to reject or
strip any unexpected keys before performing the repository update and ensure
audit fields cannot be altered by clients.

Comment on lines +15 to +23
// Check for touch capability
if ('ontouchstart' in window || navigator.maxTouchPoints > 0) {
return true;
}

// Check screen size
if (window.innerWidth <= 768) {
return true;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Touch and screen size checks may cause false positives.

The touch capability check (line 16) will classify any device with a touchscreen—including laptops and desktops with touchscreens—as mobile. Additionally, the screen width check (line 21) uses the current window size rather than device capabilities, so a desktop user with a narrow browser window would be classified as mobile.

Consider limiting mobile detection to user agent checks only, or add additional constraints (e.g., require both touch AND small screen AND mobile UA pattern) to reduce false positives.

</review_comment_end>

🤖 Prompt for AI Agents
In platforms/dreamSync/client/src/lib/utils/mobile-detection.ts around lines 15
to 23, the current detection returns true for any device with touch or small
window width which causes false positives (touch-enabled laptops and narrow
desktop windows). Change the logic to be stricter by requiring a mobile
user-agent pattern plus touch and small screen together (e.g., require
navigator.userAgent match against a mobile regex AND ('ontouchstart' in window
|| navigator.maxTouchPoints > 0) AND window.innerWidth <= 768), or alternatively
replace the current checks with a single reliable user-agent only check; update
the function to use one of these approaches and ensure tests or callers are
adjusted accordingly.

Comment on lines +28 to +32
export function getDeepLinkUrl(qrData: string): string {
// Extract the deep link URL from the QR data
// This assumes the QR data contains a URL that can be opened directly
return qrData;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Implement extraction logic or remove the function.

The function currently just returns the input parameter without any extraction, parsing, or validation. The comment suggests it should "extract the deep link URL from the QR data," but the implementation is a simple pass-through.

Either implement the actual extraction logic if QR data contains metadata/encoding that needs parsing, or remove this function entirely if no transformation is needed.

</review_comment_end>

const [wishlistContent, setWishlistContent] = useState(sampleWishlistTemplate);
const [isSaving, setIsSaving] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [existingWishlist, setExistingWishlist] = useState<any>(null);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Define a proper type for existingWishlist instead of any.

Using any bypasses TypeScript's type checking and can lead to runtime errors. Define an interface or type for the wishlist structure to ensure type safety.

Add a type definition at the top of the file:

interface Wishlist {
  id: string;
  title: string;
  content: string;
  isPublic: boolean;
  createdAt?: string;
  updatedAt?: string;
}

Then update the state declaration:

-  const [existingWishlist, setExistingWishlist] = useState<any>(null);
+  const [existingWishlist, setExistingWishlist] = useState<Wishlist | null>(null);
🤖 Prompt for AI Agents
In platforms/dreamSync/client/src/pages/wishlist-editor.tsx around line 23, the
state existingWishlist is typed as any; define a proper Wishlist interface at
the top of the file (including id, title, content, isPublic, and optional
createdAt/updatedAt) and update the useState declaration to use
useState<Wishlist | null> instead of any so TypeScript enforces the structure
across the component.

Comment on lines +85 to +96
"@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "^4.1.3",
"@types/node": "20.16.11",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.1",
"@types/turndown": "^5.0.5",
"@vitejs/plugin-react": "^4.3.2",
"autoprefixer": "^10.4.20",
"drizzle-kit": "^0.30.4",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.17",
"typescript": "5.6.3",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Blocker: @tailwindcss/vite requires Tailwind CSS v4, but you're still on 3.4.x.

The Vite plugin is only compatible with the new Tailwind v4 engine. With [email protected] the plugin throws at startup, so vite dev/build will crash. Either downgrade to the traditional PostCSS setup (remove @tailwindcss/vite and configure Tailwind 3 normally) or upgrade the entire stack to Tailwind v4 (alpha) before shipping.

🤖 Prompt for AI Agents
In platforms/dreamSync/package.json around lines 85 to 96, the dependency
@tailwindcss/vite requires Tailwind CSS v4 while package.json lists
[email protected], which will cause Vite to crash; fix by either removing
@tailwindcss/vite and revert to the PostCSS/Tailwind v3 setup (update build/vite
and postcss config to use the traditional tailwindcss plugin) or upgrade
tailwindcss and any related config/plugins to v4-compatible versions across the
project so the @tailwindcss/vite plugin can be used safely.

@@ -7,6 +7,7 @@
"name": "name",
"type": "type",
"participants": "users(participants[].id),participantIds",
"admins": "users(admins),admins",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify the admins mapping syntax for consistency.

The admins mapping uses "users(admins),admins" while the participants mapping on line 9 uses "users(participants[].id),participantIds" with explicit array notation [] and .id accessor.

If admins is an array field (like participants), the mapping should follow the same pattern for consistency. If it's a single value, the current syntax may be correct, but this needs verification against the actual data structure.

Run the following script to check the admins field structure in the Chat entity or related code:


🏁 Script executed:

#!/bin/bash
# Description: Find Chat entity definition and check admins field structure

# Search for Chat entity/model definitions
rg -nP --type=ts -A10 -B2 'class\s+Chat|interface\s+Chat' | head -50

# Search for admins field usage in chat context
rg -nP --type=ts 'admins.*:.*\[\]|admins.*Array' | head -20

Length of output: 3677


Verify admins property definition and type in Chat.ts before finalizing the mapping:


🏁 Script executed:

#!/bin/bash
# Inspect the Chat entity definition and locate the admins property
rg -nP --type=ts 'export class Chat' -A15 platforms/pictique-api/src/database/entities/Chat.ts
rg -nP --type=ts 'admins' -C3 platforms/pictique-api/src/database/entities/Chat.ts

Length of output: 476


Align admins mapping with your entity
The chat.mapping.json at line 10 defines "admins": "users(admins),admins", but the Chat entity has no admins field. Either add a corresponding admins relation in Chat.ts or remove/update this mapping to target an existing property.

🤖 Prompt for AI Agents
In platforms/pictique-api/src/web3adapter/mappings/chat.mapping.json around line
10, the mapping entry "admins": "users(admins),admins" references a non-existent
admins field on the Chat entity; fix by either adding an admins
relation/property on Chat.ts that matches the mapping (define the proper
relation type, inverse side and persistence configuration) or remove/replace the
mapping entry with the correct existing Chat property name (or adjust the
relation target to an existing entity property), then run typechecks/compile to
ensure the mapping and entity stay in sync.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant