The user router provides endpoints for managing user accounts, sessions, profiles, and administrative functions.
Queries
getCurrentUser
Get the currently authenticated user with profile and reputation data.
Access: Public (returns null if not authenticated)
Response:
{
success: boolean;
data: {
user: {
id: string;
name: string | null;
email: string;
image: string | null;
role: string;
createdAt: Date;
updatedAt: Date;
};
profile: UserProfile | null;
reputation: UserReputation | null;
} | null;
}
Example:
const { data } = await trpc.user.getCurrentUser.query();
if (data?.data) {
console.log(`Welcome ${data.data.user.name}`);
}
getMe
Get the current user’s account details.
Access: Protected
Response includes:
- User ID, name, email, image
- Handle, profile privacy settings
- Role and card background
- Account timestamps
getGithubAccount
Get the GitHub account linked to the current user.
Access: Protected
Response:
{
username: string | null;
}
getUserSessions
Get all active sessions for the current user.
Access: Protected
Response:
{
success: boolean;
data: Array<{
id: string;
ipAddress: string | null;
userAgent: string | null;
createdAt: Date;
expiresAt: Date;
}>;
}
getUserStats
Get user statistics (admin only).
Access: Admin only
Response:
{
success: boolean;
data: {
platformStats: {
totalUsers: number;
};
userStats: {
totalEarned: string;
bountiesCompleted: number;
bountiesCreated: number;
averageRating: string;
totalRatings: number;
successRate: string;
completionRate: string;
responseTime: number | null;
};
};
}
checkHandleAvailability
Check if a username handle is available.
Access: Public
Handle to check (3-20 characters)
Example:
const { available } = await trpc.user.checkHandleAvailability.query({
handle: "johndoe"
});
if (available) {
console.log("Handle is available!");
}
searchCreators
Search for users by name, handle, or ID.
Access: Protected
Search term (minimum 1 character)
Response:
{
success: boolean;
data: Array<{
id: string;
name: string | null;
handle: string | null;
image: string | null;
}>;
}
getUserActivity
Get recent activity for a user (bounties created, comments posted).
Access: Public
Number of activity items to return (1-20)
getLinkedAccounts
Get all OAuth accounts linked to the current user.
Access: Protected
Response:
{
success: boolean;
accounts: Array<{
providerId: string;
accountId: string;
}>;
}
getAllUsers (Admin)
Get paginated list of all users.
Access: Admin only
adminGetProfile (Admin)
Get detailed user profile for administration.
Access: Admin only
Response:
{
user: {
id: string;
name: string | null;
email: string;
image: string | null;
role: string;
banned: boolean | null;
createdAt: Date;
};
metrics: {
bountiesCreated: number;
};
sessions: Array<{
id: string;
createdAt: Date;
expiresAt: Date;
ipAddress: string | null;
userAgent: string | null;
}>;
}
Mutations
setHandle
Set or update the user’s handle (username).
Access: Protected
Desired handle (3-20 characters, lowercase)
Example:
const result = await trpc.user.setHandle.mutate({
handle: "johndoe"
});
console.log(result.message); // "Handle set successfully"
revokeSession
Revoke/logout a specific session.
Access: Protected
updateProfilePrivacy
Toggle profile privacy (public/private).
Access: Protected
Whether to make profile private
Example:
await trpc.user.updateProfilePrivacy.mutate({
isProfilePrivate: true
});
// Profile is now private
updateCardBackground
Set or update the user’s profile card background.
Access: Protected
Background value (pass undefined or empty to reset to default)
updateUserRole (Admin)
Update a user’s role.
Access: Admin only
Role: user, admin, or early_access
adminUpdateName (Admin)
Update a user’s display name.
Access: Admin only
New name (1-80 characters)
inviteExternalUser (Admin)
Invite a new user via email.
Access: Admin only
Example:
const result = await trpc.user.inviteExternalUser.mutate({
email: "[email protected]"
});
if (result.success) {
console.log("Invitation email sent!");
}
applyInvite
Apply an invite token to grant access.
Access: Protected
Invite token (minimum 20 characters)
Code Examples
Check Handle and Set It
import { trpc } from '@/lib/trpc';
const setUserHandle = async (desiredHandle: string) => {
// First check if available
const { available } = await trpc.user.checkHandleAvailability.query({
handle: desiredHandle
});
if (!available) {
throw new Error('Handle already taken');
}
// Set the handle
const result = await trpc.user.setHandle.mutate({
handle: desiredHandle
});
return result.handle;
};
Display User Sessions
import { trpc } from '@/lib/trpc';
const UserSessions = () => {
const { data } = trpc.user.getUserSessions.useQuery();
const revokeMutation = trpc.user.revokeSession.useMutation();
const handleRevoke = async (sessionId: string) => {
await revokeMutation.mutateAsync({ sessionId });
// Refetch sessions
};
return (
<div>
{data?.data.map(session => (
<div key={session.id}>
<p>IP: {session.ipAddress}</p>
<p>Created: {session.createdAt.toLocaleDateString()}</p>
<button onClick={() => handleRevoke(session.id)}>
Revoke
</button>
</div>
))}
</div>
);
};
Search for Users
import { trpc } from '@/lib/trpc';
import { useState } from 'react';
const UserSearch = () => {
const [query, setQuery] = useState('');
const { data, refetch } = trpc.user.searchCreators.useQuery(
{ query },
{ enabled: query.length > 0 }
);
return (
<div>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search users..."
/>
{data?.data.map(user => (
<div key={user.id}>
<img src={user.image || '/default-avatar.png'} alt={user.name || 'User'} />
<span>{user.name}</span>
<span>@{user.handle}</span>
</div>
))}
</div>
);
};