Skip to content

Ali/dev#76

Merged
jmoraispk merged 32 commits intomainfrom
ali/dev
Feb 22, 2026
Merged

Ali/dev#76
jmoraispk merged 32 commits intomainfrom
ali/dev

Conversation

@jmoraispk
Copy link
Owner

No description provided.

@vercel
Copy link

vercel bot commented Feb 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
loglife Ready Ready Preview, Comment Feb 22, 2026 10:59pm

@greptile-apps
Copy link

greptile-apps bot commented Feb 21, 2026

Greptile Summary

This PR adds WhatsApp session integration to the LogLife dashboard, allowing users to link their WhatsApp accounts and view session statistics including token usage, chat metadata, and activity status.

Major Changes:

  • New /api/sessions endpoint to fetch WhatsApp session data from a JSON file
  • Dashboard redesigned to display session stats (tokens, model, status) with real-time refresh
  • Account settings page now includes WhatsApp linking modal with UUID validation
  • Updated WhatsApp widget default message from "help" to "START"

Critical Issues:

  • Security vulnerability: /api/sessions endpoint has no authentication - anyone can access any user's session data by guessing session IDs
  • Deployment blocker: Hardcoded absolute path /home/ali/.openclaw/agents/main/sessions in API route exposes system username and won't work in other environments

Other Issues:

  • Disconnect handler doesn't properly remove the whatsappSessionId key from metadata
  • Silent error handling makes debugging difficult for users
  • Minor dependency array warning in useEffect

Confidence Score: 1/5

  • This PR has critical security vulnerabilities that expose user data and cannot be safely deployed
  • The unauthenticated API endpoint allows anyone to access sensitive session data (phone numbers, token usage, chat metadata) without authorization. Combined with a hardcoded absolute path that breaks portability, these are blocking issues that must be fixed before merge
  • Pay critical attention to website/app/api/sessions/route.ts - must add authentication and fix hardcoded path before deployment

Important Files Changed

Filename Overview
website/app/api/sessions/route.ts New API endpoint with critical security issues: missing authentication allows unauthorized session data access, hardcoded absolute path breaks portability
website/app/dashboard/page.tsx Dashboard redesigned to display WhatsApp session data with stats, token usage visualization, and activity feed. Minor issues with error handling and dependency array
website/app/account/page.tsx Added WhatsApp account linking UI with modal, UUID validation, and connect/disconnect functionality. Disconnect handler doesn't properly remove metadata key
website/app/components/WhatsAppWidget.tsx Updated default WhatsApp message from "help" to "START" - simple string change with no issues

Sequence Diagram

sequenceDiagram
    participant User
    participant Account as Account Page
    participant Clerk
    participant Dashboard
    participant API as /api/sessions
    participant FS as File System

    User->>Account: Enter WhatsApp Session ID
    Account->>Account: Validate UUID format
    Account->>Clerk: Update user.unsafeMetadata
    Clerk-->>Account: Success
    Account-->>User: "Session linked successfully"
    
    User->>Dashboard: Navigate to Dashboard
    Dashboard->>Clerk: Get user.unsafeMetadata
    Clerk-->>Dashboard: whatsappSessionId
    Dashboard->>API: GET /api/sessions?sessionId={id}
    Note over API: ⚠️ No auth check!
    API->>FS: Read /home/ali/.openclaw/.../sessions.json
    FS-->>API: Session data
    API-->>Dashboard: Session stats (tokens, model, status)
    Dashboard-->>User: Display session data & visualizations
Loading

Last reviewed commit: 009c4af

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

4 files reviewed, 6 comments

Edit Code Review Agent Settings | Greptile


try {
// const filePath = join(process.cwd(), "..", "sessions.json");
const filePath = join("/home/ali/.openclaw/agents/main/sessions", "sessions.json");
Copy link

Choose a reason for hiding this comment

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

Hardcoded absolute path /home/ali/.openclaw/agents/main/sessions exposes system username and creates deployment issues.

Suggested change
const filePath = join("/home/ali/.openclaw/agents/main/sessions", "sessions.json");
const filePath = join(process.cwd(), "sessions.json");

Comment on lines 5 to 66
export async function GET(req: NextRequest) {
const sessionId = req.nextUrl.searchParams.get("sessionId");
const key = req.nextUrl.searchParams.get("key");

if (!sessionId && !key) {
return NextResponse.json({ error: "Provide ?sessionId= or ?key=" }, { status: 400 });
}

try {
// const filePath = join(process.cwd(), "..", "sessions.json");
const filePath = join("/home/ali/.openclaw/agents/main/sessions", "sessions.json");
const raw = await readFile(filePath, "utf-8");
const sessions: Record<string, Record<string, unknown>> = JSON.parse(raw);

let session: Record<string, unknown> | undefined;
let matchedKey = key || "";

if (key) {
session = sessions[key];
} else if (sessionId) {
for (const [k, v] of Object.entries(sessions)) {
if (v.sessionId === sessionId) {
session = v;
matchedKey = k;
break;
}
}
}

if (!session) {
return NextResponse.json({ error: "Session not found" }, { status: 404 });
}

const origin = session.origin as Record<string, string> | undefined;
const delivery = session.deliveryContext as Record<string, string> | undefined;

return NextResponse.json({
sessionKey: matchedKey,
sessionId: session.sessionId ?? "",
updatedAt: session.updatedAt ?? 0,
abortedLastRun: session.abortedLastRun ?? false,
chatType: session.chatType ?? origin?.chatType ?? "unknown",
lastChannel: session.lastChannel ?? delivery?.channel ?? "unknown",
origin: {
label: origin?.label ?? "Unknown",
from: origin?.from ?? "",
to: origin?.to ?? "",
},
deliveryContext: {
channel: delivery?.channel ?? "unknown",
to: delivery?.to ?? "",
},
compactionCount: session.compactionCount ?? 0,
inputTokens: session.inputTokens ?? 0,
outputTokens: session.outputTokens ?? 0,
totalTokens: session.totalTokens ?? 0,
model: session.model ?? "unknown",
});
} catch {
return NextResponse.json({ error: "Failed to read sessions" }, { status: 500 });
}
}
Copy link

Choose a reason for hiding this comment

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

No authentication check - anyone can access session data by guessing session IDs or keys. This endpoint exposes sensitive user session information including phone numbers (from, to), token usage, and session metadata without verifying the requester is authorized.

Add authentication middleware:

import { auth } from "@clerk/nextjs";

export async function GET(req: NextRequest) {
  const { userId } = auth();
  if (!userId) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  
  // Then verify the requested session belongs to this user
  // by checking user.unsafeMetadata.whatsappSessionId matches

Comment on lines 74 to 75
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => { fetchSession(); }, [whatsappSessionId]);
Copy link

Choose a reason for hiding this comment

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

Missing fetchSession in the dependency array will cause the linter warning. Since you're disabling the exhaustive-deps rule, this useEffect will only run when whatsappSessionId changes, but won't pick up changes to fetchSession if it were to be redefined.

Suggested change
// eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => { fetchSession(); }, [whatsappSessionId]);
useEffect(() => { fetchSession(); }, [whatsappSessionId, fetchSession]);

Comment on lines 67 to 71
fetch(`/api/sessions?sessionId=${encodeURIComponent(whatsappSessionId)}`)
.then((res) => res.json())
.then((data) => { if (!data.error) setSession(data); else setSession(null); })
.catch(() => { setSession(null); })
.finally(() => { setSessionLoading(false); setRefreshing(false); });
Copy link

Choose a reason for hiding this comment

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

Fetch error responses are silently ignored, making debugging difficult for users when the API fails.

Consider logging errors or showing a user-friendly error state:

.catch((err) => { 
  console.error('Failed to fetch session:', err);
  setSession(null); 
})

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines 159 to 167
const handleWhatsAppDisconnect = async () => {
try {
await user!.update({
unsafeMetadata: { ...user!.unsafeMetadata, whatsappSessionId: undefined },
});
} catch {
// silently fail
}
};
Copy link

Choose a reason for hiding this comment

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

Setting whatsappSessionId to undefined doesn't remove the key from unsafeMetadata, it sets it to undefined. To actually remove it, you should omit the key entirely or set it to null, and provide user feedback.

const handleWhatsAppDisconnect = async () => {
  try {
    const { whatsappSessionId, ...rest } = user!.unsafeMetadata as Record<string, unknown>;
    await user!.update({ unsafeMetadata: rest });
    setWhatsAppMessage({ type: "success", text: "WhatsApp disconnected successfully!" });
  } catch {
    setWhatsAppMessage({ type: "error", text: "Failed to disconnect. Please try again." });
  }
};

Copy link
Owner Author

Choose a reason for hiding this comment

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

@greptileai are you there?

Copy link

Choose a reason for hiding this comment

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

Yes, I'm here! How can I help you with this code?

@greptile-apps
Copy link

greptile-apps bot commented Feb 21, 2026

Additional Comments (1)

website/app/account/page.tsx
Input automatically trims on change, but validation checks the trimmed value. This means users can't see trailing/leading spaces they might accidentally paste.

                  onChange={(e) => setWhatsAppSessionId(e.target.value)}

Then keep the trim only in the submit handler (line 130).

jmoraispk and others added 2 commits February 21, 2026 16:16
Rewrite README and plugin/README with end-to-end setup instructions
(OpenClaw install, plugin linking, API key, website .env). Fix OpenClaw
GitHub URL. Make apiKey optional in plugin schema so install succeeds
before configuration. Rename plugin package to match manifest ID.

Co-authored-by: Cursor <cursoragent@cursor.com>
Included a new "self-hosting" page in the documentation and updated the index layout to feature both "Quickstart" and "Self-hosting" cards for improved user navigation.
Introduced a new documentation page titled "OpenClaw tricks" that provides useful tips for managing OpenClaw instances, including instructions for password-protecting the web UI with Nginx. Updated the index to include the new section for improved navigation.
- Changed the deployment step name to "Deploy plugin and restart gateway" for clarity.
- Added health checks to the deployment process to verify plugin functionality after restart.
- Updated the development documentation to reflect the new local setup instructions and API endpoint details.
- Removed outdated AI tools documentation and unnecessary sections to streamline content.
- Revised the API reference to include new endpoints for session management and verification.
- Introduced a new "Networking" guide detailing reverse proxy setup with Caddy for HTTPS and access control.
- Updated development documentation to clarify CI/CD requirements and environment variables.
- Added a new automated setup script to streamline the installation and configuration process for the LogLife plugin.
- Included additional security measures in the documentation, emphasizing HTTPS and layered authentication for the Control UI.
- Introduced a new declaration file to provide type definitions for the OpenClaw plugin SDK.
- This allows TypeScript compilation in CI environments without requiring the OpenClaw runtime.
- Updated package.json to remove unnecessary dependencies.
- Simplified the update process for user metadata by removing the whatsappPhone property directly.
- Improved error handling by replacing silent failure with an alert message for better user feedback.
@jmoraispk jmoraispk merged commit 020dfb2 into main Feb 22, 2026
4 checks passed
@jmoraispk jmoraispk deleted the ali/dev branch February 22, 2026 23:00
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.

2 participants