diff --git a/server/scripts/import-boundaries-baseline.json b/server/scripts/import-boundaries-baseline.json index 94d14b60c..231bd4cd6 100644 --- a/server/scripts/import-boundaries-baseline.json +++ b/server/scripts/import-boundaries-baseline.json @@ -16,16 +16,13 @@ "places -> accommodations", "places -> assignments", "plugins -> trips", - "plugins -> vacay", "reservations -> integrations", "trip-members -> auth", "trip-members -> trips", "trip-read-model -> trip-members", "trip-read-model -> trips", "trips -> trip-members", - "trips -> trip-read-model", - "trips -> vacay", - "vacay -> auth" + "trips -> trip-read-model" ], "sharedImportsDomain": [ "nest/common/idempotency-cleanup.job.ts -> nest/audit/audit-log.logger.ts", diff --git a/server/src/nest/vacay/vacay.mcp.ts b/server/src/nest/vacay/vacay.mcp.ts index c5a280b47..e11ac6e7e 100644 --- a/server/src/nest/vacay/vacay.mcp.ts +++ b/server/src/nest/vacay/vacay.mcp.ts @@ -12,7 +12,9 @@ import { vacayUpdatePlanRequestSchema, } from '@trek/shared'; import type { VacayUpdatePlanRequest } from '@trek/shared'; -import { AuthService } from '../auth/auth.service'; +import { InjectRepository } from '@mikro-orm/nestjs'; +import { Users } from '../../db/entities/Users.entity'; +import type { UsersRepository } from '../../db/repositories/Users.repository'; import { ADDON_IDS } from '../../addons'; import { VacayService } from './vacay.service'; import { addonGate } from '../addons/addon-gate'; @@ -79,7 +81,8 @@ function calendarRegionCodes(country: string, data: unknown): { region: string; export class VacayMcp { constructor( private readonly vacay: VacayService, - private readonly auth: AuthService, + // The invite and share tools need the caller's username and email. + @InjectRepository(Users) private readonly users: UsersRepository, readonly addons: AddonsService, ) {} @@ -180,7 +183,7 @@ export class VacayMcp { }) async sendVacayInvite({ targetUserId }: { targetUserId: number }, ctx: McpContext) { const planId = await this.vacay.getActivePlanId(ctx.userId); - const me = await this.auth.getCurrentUser(ctx.userId); + const me = await this.users.findUsernameEmail(ctx.userId); if (!me) return errorResult('User not found.'); const result = await this.vacay.sendInvite(planId, ctx.userId, me.username, me.email, targetUserId); if (result.error) return errorResult(result.error); @@ -559,7 +562,7 @@ export class VacayMcp { access: { group: 'vacay', mode: 'write' }, }) async shareVacayCalendar({ targetUserId }: { targetUserId: number }, ctx: McpContext) { - const me = await this.auth.getCurrentUser(ctx.userId); + const me = await this.users.findUsernameEmail(ctx.userId); if (!me) return errorResult('User not found.'); const result = await this.vacay.shareCalendar(ctx.userId, me.email, targetUserId); if (result.error) return errorResult(result.error); diff --git a/server/src/nest/vacay/vacay.module.ts b/server/src/nest/vacay/vacay.module.ts index 2fbec8991..3237cbc37 100644 --- a/server/src/nest/vacay/vacay.module.ts +++ b/server/src/nest/vacay/vacay.module.ts @@ -5,7 +5,7 @@ import { VacayService } from './vacay.service'; import { VacayRpc } from './vacay.rpc'; import { PluginGuardsModule } from '../../nest-rpc/plugin-guards.module'; import { VacayMcp } from './vacay.mcp'; -import { AuthModule } from '../auth/auth.module'; +import { Users } from '../../db/entities/Users.entity'; import { AddonsModule } from '../addons/addons.module'; import { NotificationsModule } from '../notifications/notifications.module'; import { VacayPlans } from '../../db/entities/VacayPlans.entity'; @@ -37,13 +37,14 @@ import { SchoolHolidayRegions } from '../../db/entities/SchoolHolidayRegions.ent @Module({ imports: [ NotificationsModule, - AuthModule, PluginGuardsModule, AddonsModule, MikroOrmModule.forFeature([ VacayPlans, VacayPlanMembers, VacayYears, VacayUserYears, VacayUserColors, VacayEntries, VacayCompanyHolidays, VacayHolidayCalendars, VacayShares, VacayUserSettings, SchoolHolidayRegions, + // VacayMcp's invite and share tools read the caller's username/email. + Users, ]), ], controllers: [VacayController], diff --git a/server/tests/helpers/mcp-test-controllers.ts b/server/tests/helpers/mcp-test-controllers.ts index ce465bfcb..ff143c54b 100644 --- a/server/tests/helpers/mcp-test-controllers.ts +++ b/server/tests/helpers/mcp-test-controllers.ts @@ -7,7 +7,6 @@ import { AssignmentsMcp } from '../../src/nest/assignments/assignments.mcp'; import { AssignmentsService } from '../../src/nest/assignments/assignments.service'; import { AtlasMcp } from '../../src/nest/atlas/atlas.mcp'; import { AtlasService } from '../../src/nest/atlas/atlas.service'; -import { AuthService } from '../../src/nest/auth/auth.service'; import { BudgetMcp } from '../../src/nest/budget/budget.mcp'; import { BudgetService } from '../../src/nest/budget/budget.service'; import { ExchangeRatesService } from '../../src/nest/budget/exchange-rates.service'; @@ -73,9 +72,7 @@ import { TrekPhotoCacheMeta } from '../../src/db/entities/TrekPhotoCacheMeta.ent import { PhotoProviders } from '../../src/db/entities/PhotoProviders.entity'; import { UnsplashService } from '../../src/nest/unsplash/unsplash.service'; import { UserCleanupService } from '../../src/nest/auth/user-cleanup.service'; -import { WebauthnConfigService } from '../../src/nest/auth/webauthn-config.service'; import { TripMembershipService } from '../../src/nest/trip-membership/trip-membership.service'; -import { MailerService } from '../../src/nest/notifications/mailer/mailer.service'; import { CalendarService } from '../../src/nest/calendar/calendar.service'; import { FeedsMcp } from '../../src/nest/feeds/feeds.mcp'; import { FeedsService } from '../../src/nest/feeds/feeds.service'; @@ -182,18 +179,10 @@ import { createTestJourneyShareTokensRepo } from './journey-share-repos'; import { AppSettings } from '../../src/db/entities/AppSettings.entity'; import { AuditLog } from '../../src/db/entities/AuditLog.entity'; import { Users } from '../../src/db/entities/Users.entity'; -import { Settings } from '../../src/db/entities/Settings.entity'; -import { InviteTokens } from '../../src/db/entities/InviteTokens.entity'; -import { McpTokens } from '../../src/db/entities/McpTokens.entity'; -import { OauthTokens } from '../../src/db/entities/OauthTokens.entity'; -import { WebauthnCredentials } from '../../src/db/entities/WebauthnCredentials.entity'; -import { PasswordResetTokens } from '../../src/db/entities/PasswordResetTokens.entity'; import { noGoogleQuota } from './google-quota'; -import { createTestPushSubscriptionsRepo } from './notifications-repos'; import { createTestToursRepo } from './tours-repos'; import { createTestBudgetSettlementsRepo } from './budget-repos'; import { MaintenanceRepository } from '../../src/db/repositories/MaintenanceRepository'; -import { createTestSessionsService } from './sessions'; /** * Hand-wired counterpart of the boot-time discovery in McpRegistryService, @@ -214,36 +203,13 @@ export async function createMcpTestRegistry(): Promise { const appSettings = (await createTestOrm(db)).repo(AppSettings); const auditLogRepo = mcpOrm.repo(AuditLog); const usersRepo = mcpOrm.repo(Users); - const settingsRepo = mcpOrm.repo(Settings); - const inviteTokensRepo = mcpOrm.repo(InviteTokens); - const mcpTokensRepoForAuth = mcpOrm.repo(McpTokens); - const oauthTokensRepo = mcpOrm.repo(OauthTokens); - const webauthnCredentialsRepoForAuth = mcpOrm.repo(WebauthnCredentials); - const passwordResetTokensRepo = mcpOrm.repo(PasswordResetTokens); const permissionsService = new PermissionsService(await createTestAppSettingsRepo(db), await createTestUnitOfWork(db)); - // Same argument list as auth.bridge.ts. AtlasService used to sit in third - // place; when getTravelStats moved onto AtlasService itself the edge was - // dropped and four collaborators took its place, but this call site kept the - // old shape, so `membership` and `webauthn` held the wrong objects and - // userCleanup/mailer/tokens were undefined. const realtimeService = new RealtimeService(); // Plan 4 Task 1 constructor-ripple: the trip `user_id`/user `role` reads // moved off `DatabaseService` onto `TripsRepository`/`UsersRepository`. const guards = new McpToolGuardsService(mcpOrm.repo(Trips), usersRepo, permissionsService, realtimeService); const exchangeRatesService = new ExchangeRatesService(); const budgetService = new BudgetService(permissionsService, exchangeRatesService, realtimeService, await createTestUnitOfWork(db), ...(await budgetRepoArgs(db))); - const authService = new AuthService( - permissionsService, - new TripMembershipService(await createTestTripsRepo(db), await createTestTripMembersRepo(db)), - new WebauthnConfigService(appSettings), - new UserCleanupService(new MaintenanceRepository(mcpOrm.em), budgetService, await createTestUnitOfWork(db), usersRepo, await createTestTripMembersRepo(db), await createTestBudgetItemsRepo(db), await createTestBudgetSettlementsRepo(db), await createTestJourneyShareTokensRepo(db), await createTestJourneysRepo(db), await createTestJourneyEntriesRepo(db), await createTestJourneyContributorsRepo(db), await createTestShareTokensRepo(db), await createTestPluginsRepo(db), await createTestPluginUserErasureQueueRepo(db)), - new MailerService(usersRepo, settingsRepo, appSettings), - new EphemeralTokenService(), - new AllowedFileTypesService(appSettings), await createTestUnitOfWork(db), - appSettings, usersRepo, inviteTokensRepo, mcpTokensRepoForAuth, oauthTokensRepo, webauthnCredentialsRepoForAuth, passwordResetTokensRepo, - await createTestPushSubscriptionsRepo(db), - await createTestSessionsService(db), - ); const queryHelpersService = new QueryHelpersService(await createTestTagsRepo(db), await createTestPlaceRatingsRepo(db), await createTestAssignmentParticipantsRepo(db)); const daysService = new DaysService( permissionsService, @@ -453,7 +419,7 @@ export async function createMcpTestRegistry(): Promise { await createTestVacaySharesRepo(db), await createTestVacayUserSettingsRepo(db), await createTestSchoolHolidayRegionsRepo(db), realtimeService, notificationsStub(), await createTestUnitOfWork(db), - ), authService, addonsService), + ), usersRepo, addonsService), new SchoolHolidaysMcp( new SchoolHolidaysService( await createTestSchoolHolidayCountriesRepo(db),