User Authentication
Relevant source files
The following files were used as context for generating this wiki page:
User Authentication in TalkCRM is a multi-faceted system designed to identify and authorize users across various interaction channels, including the web application, voice calls via phone, and Slack. The core principle is to link different identifiers (email, phone number, Salesforce User ID, Slack User ID) to a single, unified user record in the Convex database. This ensures that regardless of how a user interacts with the service, their actions are correctly attributed and their permissions are consistently enforced.
The system employs several distinct authentication mechanisms: phone-based verification for voice services, web-based authentication for the dashboard, and OAuth 2.0 flows for third-party integrations like Salesforce and Slack. Each mechanism is tailored to its specific context while contributing to a central user identity model.
Core Authentication Mechanisms
TalkCRM uses different primary authentication methods for its web and voice interfaces.
Web Application Authentication (WorkOS)
The web application, which serves as the installation and dashboard portal, uses WorkOS for user authentication. The frontend, built with React, leverages the @workos-inc/authkit-react library to manage user sessions.
- The main
Appcomponent uses theuseAuthhook to check the user's authentication state (isLoading,user). - If a user is not authenticated, the
LandingPageorLoginPageis displayed. - Once authenticated, the
userobject is available, and the mainInstallationPageis rendered, providing access to setup instructions and integration settings. - The
userobject from WorkOS contains the user's email, which is the primary identifier for linking to the TalkCRM user record for other integrations like Slack.
Sources: src/App.tsx:18-20, 48-68
Phone-Based Authentication (Voice & SMS)
Phone-based authentication is critical for the core voice service and AI-powered texting features. It serves two main purposes: identifying users during incoming calls and providing a secure signup/login mechanism.
Incoming Call Authentication (Caller ID)
When a user calls the TalkCRM Twilio number, the system authenticates them based on their caller ID.
The following diagram illustrates the incoming call authentication flow:
This flow is handled by the /webhooks/twilio/incoming endpoint. It extracts the From number and uses the internal.users.getUserByPhoneInternal query to find a matching user. If a valid, active user is found, the call is connected to the ElevenLabs AI agent with the user's context. Otherwise, the call is rejected.
Sources: convex/http.ts:1330-1398, convex/users.ts:68-85
Phone Verification Signup & Login
For new users or users logging in via the web, TalkCRM uses a two-step phone verification process powered by SendBlue. This flow is managed by a set of API endpoints.
The diagram below shows the sequence for a new user signup:
Key Endpoints:
| Endpoint | Method | Description | Source File |
|---|---|---|---|
/api/auth/signup/start | POST | Initiates signup for a new user. Checks if the email exists, then triggers a verification SMS. | convex/http.ts:1417-1444 |
/api/auth/login/start | POST | Initiates login for an existing user. Checks if the phone number is registered, then triggers a verification SMS. | convex/http.ts:1472-1505 |
/api/auth/verify | POST | Completes the signup/login process by verifying the SMS code. On success, creates the user (if new) and returns an auth token. | convex/http.ts:1447-1470 |
/api/auth/add-phone | POST | Starts the verification process to add a new phone number to an existing user account. | convex/http.ts:1507-1542 |
Sources: convex/http.ts:1403-1542
Third-Party Integrations
Authentication extends to third-party services like Salesforce and Slack, enabling TalkCRM to act on the user's behalf. This is accomplished via OAuth 2.0.
Salesforce OAuth 2.0
Connecting to Salesforce is a cornerstone of the application. TalkCRM supports two distinct OAuth flows to accommodate different connection scenarios.
1. Web App OAuth Flow
This flow is for users who sign up and connect their Salesforce account directly from the TalkCRM web application.
- Initiation: A GET request to
/auth/salesforce/connectstarts the flow. - Identity: It uses a single, centralized Salesforce Connected App, identified by
SALESFORCE_CLIENT_IDfrom environment variables. - State: A
stateparameter is generated containing theuserIdand areturnUrlto redirect the user back to the web app after completion.
Sources: convex/http.ts:1873-1906
2. Salesforce LWC (Package) OAuth Flow
This multi-tenant flow is designed to be initiated from the TalkCRM Setup wizard within a customer's Salesforce org. It uses per-org Connected App credentials.
- Initiation: The LWC (
talkCrmSetup.js) redirects the user to/auth/salesforce/initiate. It passes the org'sinstance_urland acallback_urlto return to the LWC. - Identity: The backend looks up the org's specific Connected App
consumerKeyandconsumerSecretfrom theorgCredentialstable based on theinstanceUrl. - Callback: After authorization, Salesforce redirects to
/auth/salesforce/callback. The backend exchanges the authorization code for tokens using the org-specific credentials. - User Linking: The system finds or creates a TalkCRM user based on the email from the Salesforce user info endpoint. The
talkcrm_user_idis then passed back to the LWC as a URL hash parameter. - LWC Handling: The
talkCrmSetup.jscomponent checks fortalkcrm_user_idin the URL on load, saves the connection via an Apex controller, and proceeds to the next setup step (phone verification).
The following diagram shows the LWC OAuth flow:
Slack OAuth 2.0
The Slack integration follows a standard OAuth flow to allow the app to send notifications and respond to commands.
- Initiation: The
getInstallUrlaction inconvex/slackAuth.tsgenerates the OAuth URL, including required scopes and a CSRFstatetoken. - Callback: The
/api/slack/oauth/callbackendpoint inconvex/http.tshandles the response from Slack. - Token Exchange: The
completeOAuthFlowinternal action validates the state, exchanges thecodefor abotToken, and fetches user/team information. - User Linking: It links the Slack installation to a TalkCRM user, either from the
userIdin the state or by looking up the user's email. - Storage: The installation details, including the
botTokenandteamId, are saved to theslackInstallationstable.
Sources: convex/slackAuth.ts:1-200, convex/http.ts:2513-2550
User Data Model and Functions
The users table is the central hub for identity. All authentication methods ultimately resolve to a user record in this table.
User Schema (Inferred)
| Field | Type | Description | Source |
|---|---|---|---|
email | string | The user's unique email address (lowercased). | convex/users.ts:154 |
name | string | The user's full name. | convex/users.ts:155 |
verifiedPhones | Array<string> | An array of E.164 formatted phone numbers verified by the user. | convex/users.ts:156 |
primaryPhone | string | The primary phone number for the user. | convex/users.ts:157 |
status | "active" | "pending" | The user's account status. pending until a phone is verified. | convex/users.ts:158 |
createdAt | number | Timestamp of when the user was created. | convex/users.ts:159 |
lastLoginAt | number | Timestamp of the user's last login. | convex/users.ts:241 |
tier | string | User's subscription tier (e.g., "free"). | convex/users.ts:160 |
Sources: convex/users.ts
Key Authentication Functions
The convex/users.ts file contains several utility and database functions crucial for authentication.
| Function | Type | Description |
|---|---|---|
normalizePhone(phone) | Utility | Converts a phone number string into E.164 format (e.g., +14155551234). |
generateVerificationCode() | Utility | Creates a 6-digit random code for phone verification. |
getUserByPhone(phone) | Query | Finds a user whose verifiedPhones array contains the specified number. |
getUserByEmail(email) | Query | Finds a user by their email address. |
createUser(...) | Mutation | Creates a new user record after successful phone verification. |
addPhoneToUser(...) | Mutation | Adds a new verified phone number to an existing user's record. |
startPhoneVerification(...) | Mutation | Creates a phoneVerifications record with a code and expiry. |
verifyPhoneCode(...) | Mutation | Validates a verification code and links the phone to a user. |
createUserWithoutPhone(...) | Internal Mutation | Creates a user with pending status during an OAuth flow before a phone is added. |
Sources: convex/users.ts
Summary
TalkCRM's authentication architecture is robust and flexible, designed to securely manage user identity across its web, voice, and third-party integration surfaces. It combines standard web authentication (WorkOS), a secure phone verification system, and multiple OAuth 2.0 flows. All these paths converge on a central user model in Convex, which uses the user's phone number for real-time voice call identification and email for linking web and integration identities. This design provides both a seamless user experience and the necessary security and context to power the application's core features.