import { z } from 'zod';
import { pocketBaseService, PocketBaseError } from '../pocketbase-service.js';
import { logger } from '../utils/logger.js';
import { LoginParamsSchema, RegisterParamsSchema, RequestPasswordResetParamsSchema, ConfirmPasswordResetParamsSchema, } from '../types/mcp.js';
// Helper function to create tool results
function createResult(text, isError = false, meta) {
const result = {
content: [{ type: 'text', text }],
isError,
};
if (meta !== undefined) {
result._meta = meta;
}
return result;
}
// Helper function to validate parameters
function validateParams(schema, params) {
try {
return schema.parse(params);
}
catch (error) {
if (error instanceof z.ZodError) {
const errors = error.errors.map((err) => `${err.path.join('.')}: ${err.message}`);
throw new Error(`Invalid parameters:\n${errors.join('\n')}`);
}
throw error;
}
}
// User login tool
export const loginTool = {
name: 'pb_auth_login',
description: 'Authenticate a user with email and password',
inputSchema: {
type: 'object',
properties: {
email: {
type: 'string',
format: 'email',
description: 'User email address',
},
password: {
type: 'string',
description: 'User password',
},
options: {
type: 'object',
properties: {
expand: {
type: 'string',
description: 'Relations to expand',
},
fields: {
type: 'string',
description: 'Fields to return',
},
},
},
},
required: ['email', 'password'],
},
};
export async function handleLogin(params) {
try {
const { email, password, options } = validateParams(LoginParamsSchema, params);
logger.info('Processing login request', { email });
const authOptions = options ? {
...(options.expand && { expand: options.expand }),
...(options.fields && { fields: options.fields }),
} : undefined;
const authData = await pocketBaseService.loginUser(email, password, authOptions);
const result = {
success: true,
user: {
id: authData.record.id,
email: authData.record.email,
username: authData.record.username,
verified: authData.record.verified,
created: authData.record.created,
updated: authData.record.updated,
},
token: authData.token,
};
return createResult(`Login successful for user: ${email}`, false, result);
}
catch (error) {
logger.error('Login failed', error);
if (error instanceof PocketBaseError) {
return createResult(`Login failed: ${error.message}`, true, { error: error.message, status: error.status });
}
const message = error instanceof Error ? error.message : 'Unknown error occurred';
return createResult(`Login failed: ${message}`, true);
}
}
// User registration tool
export const registerTool = {
name: 'pb_auth_register',
description: 'Register a new user account',
inputSchema: {
type: 'object',
properties: {
email: {
type: 'string',
format: 'email',
description: 'User email address',
},
password: {
type: 'string',
minLength: 8,
description: 'User password (minimum 8 characters)',
},
passwordConfirm: {
type: 'string',
minLength: 8,
description: 'Password confirmation',
},
username: {
type: 'string',
description: 'Optional username',
},
name: {
type: 'string',
description: 'Optional display name',
},
},
required: ['email', 'password', 'passwordConfirm'],
},
};
export async function handleRegister(params) {
try {
const { email, password, passwordConfirm, username, name, } = validateParams(RegisterParamsSchema, params);
if (password !== passwordConfirm) {
return createResult('Registration failed: Password confirmation does not match', true);
}
logger.info('Processing registration request', { email, username });
const additionalData = {};
if (username)
additionalData.username = username;
if (name)
additionalData.name = name;
const authData = await pocketBaseService.registerUser(email, password, passwordConfirm, additionalData);
const result = {
success: true,
user: {
id: authData.record.id,
email: authData.record.email,
username: authData.record.username,
verified: authData.record.verified,
created: authData.record.created,
updated: authData.record.updated,
},
token: authData.token,
};
return createResult(`Registration successful for user: ${email}`, false, result);
}
catch (error) {
logger.error('Registration failed', error);
if (error instanceof PocketBaseError) {
return createResult(`Registration failed: ${error.message}`, true, { error: error.message, status: error.status });
}
const message = error instanceof Error ? error.message : 'Unknown error occurred';
return createResult(`Registration failed: ${message}`, true);
}
}
// Refresh authentication token tool
export const refreshAuthTool = {
name: 'pb_auth_refresh',
description: 'Refresh the current user authentication token',
inputSchema: {
type: 'object',
properties: {
expand: {
type: 'string',
description: 'Relations to expand',
},
fields: {
type: 'string',
description: 'Fields to return',
},
},
},
};
export async function handleRefreshAuth(params) {
try {
const options = params;
logger.info('Processing auth refresh request');
const authData = await pocketBaseService.refreshUserAuth(options);
const result = {
success: true,
user: {
id: authData.record.id,
email: authData.record.email,
username: authData.record.username,
verified: authData.record.verified,
created: authData.record.created,
updated: authData.record.updated,
},
token: authData.token,
};
return createResult('Authentication token refreshed successfully', false, result);
}
catch (error) {
logger.error('Auth refresh failed', error);
if (error instanceof PocketBaseError) {
return createResult(`Auth refresh failed: ${error.message}`, true, { error: error.message, status: error.status });
}
const message = error instanceof Error ? error.message : 'Unknown error occurred';
return createResult(`Auth refresh failed: ${message}`, true);
}
}
// Logout tool
export const logoutTool = {
name: 'pb_auth_logout',
description: 'Logout the current user and clear authentication',
inputSchema: {
type: 'object',
properties: {},
},
};
export async function handleLogout() {
try {
logger.info('Processing logout request');
pocketBaseService.logoutUser();
return createResult('User logged out successfully', false, { success: true });
}
catch (error) {
logger.error('Logout failed', error);
const message = error instanceof Error ? error.message : 'Unknown error occurred';
return createResult(`Logout failed: ${message}`, true);
}
}
// Get current user tool
export const getCurrentUserTool = {
name: 'pb_auth_get_user',
description: 'Get information about the currently authenticated user',
inputSchema: {
type: 'object',
properties: {},
},
};
export async function handleGetCurrentUser() {
try {
logger.info('Getting current user info');
const user = pocketBaseService.getCurrentUser();
const isAuthenticated = pocketBaseService.isUserAuthenticated();
if (!isAuthenticated || !user) {
return createResult('No user is currently authenticated', false, { authenticated: false, user: null });
}
const result = {
authenticated: true,
user: {
id: user.id,
email: user.email,
username: user.username,
verified: user.verified,
emailVisibility: user.emailVisibility,
created: user.created,
updated: user.updated,
},
};
return createResult(`Current user: ${user.email}`, false, result);
}
catch (error) {
logger.error('Get current user failed', error);
const message = error instanceof Error ? error.message : 'Unknown error occurred';
return createResult(`Failed to get current user: ${message}`, true);
}
}
// Request password reset tool
export const requestPasswordResetTool = {
name: 'pb_auth_request_password_reset',
description: 'Request a password reset email for a user',
inputSchema: {
type: 'object',
properties: {
email: {
type: 'string',
format: 'email',
description: 'Email address to send password reset to',
},
},
required: ['email'],
},
};
export async function handleRequestPasswordReset(params) {
try {
const { email } = validateParams(RequestPasswordResetParamsSchema, params);
logger.info('Processing password reset request', { email });
const success = await pocketBaseService.requestPasswordReset(email);
if (success) {
return createResult(`Password reset email sent to: ${email}`, false, { success: true, email });
}
return createResult('Failed to send password reset email', true);
}
catch (error) {
logger.error('Password reset request failed', error);
if (error instanceof PocketBaseError) {
return createResult(`Password reset request failed: ${error.message}`, true, { error: error.message, status: error.status });
}
const message = error instanceof Error ? error.message : 'Unknown error occurred';
return createResult(`Password reset request failed: ${message}`, true);
}
}
// Confirm password reset tool
export const confirmPasswordResetTool = {
name: 'pb_auth_confirm_password_reset',
description: 'Confirm a password reset with the reset token',
inputSchema: {
type: 'object',
properties: {
token: {
type: 'string',
description: 'Password reset token from email',
},
password: {
type: 'string',
minLength: 8,
description: 'New password (minimum 8 characters)',
},
passwordConfirm: {
type: 'string',
minLength: 8,
description: 'New password confirmation',
},
},
required: ['token', 'password', 'passwordConfirm'],
},
};
export async function handleConfirmPasswordReset(params) {
try {
const { token, password, passwordConfirm } = validateParams(ConfirmPasswordResetParamsSchema, params);
if (password !== passwordConfirm) {
return createResult('Password reset failed: Password confirmation does not match', true);
}
logger.info('Processing password reset confirmation');
const success = await pocketBaseService.confirmPasswordReset(token, password, passwordConfirm);
if (success) {
return createResult('Password reset completed successfully', false, { success: true });
}
return createResult('Failed to reset password', true);
}
catch (error) {
logger.error('Password reset confirmation failed', error);
if (error instanceof PocketBaseError) {
return createResult(`Password reset confirmation failed: ${error.message}`, true, { error: error.message, status: error.status });
}
const message = error instanceof Error ? error.message : 'Unknown error occurred';
return createResult(`Password reset confirmation failed: ${message}`, true);
}
}
// Export all auth tools and handlers
export const authTools = [
loginTool,
registerTool,
refreshAuthTool,
logoutTool,
getCurrentUserTool,
requestPasswordResetTool,
confirmPasswordResetTool,
];
export const authHandlers = {
pb_auth_login: handleLogin,
pb_auth_register: handleRegister,
pb_auth_refresh: handleRefreshAuth,
pb_auth_logout: handleLogout,
pb_auth_get_user: handleGetCurrentUser,
pb_auth_request_password_reset: handleRequestPasswordReset,
pb_auth_confirm_password_reset: handleConfirmPasswordReset,
};
//# sourceMappingURL=auth.js.map