Backend frontend agent#1849
Conversation
…entication and CRUD operations - Add SitenovaSiteController for handling user registration, login, and data operations. - Create SitenovaModule to encapsulate the microservice's functionality and dependencies. - Implement use cases for registering and logging in end-users, executing raw queries, and managing data. - Introduce interfaces for use cases to ensure consistent implementation. - Enhance public CORS middleware to support new Sitenova routes. - Develop end-to-end tests for user authentication and data management functionalities.
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughSitenova is added to the backend with new contracts, guards, use cases, controllers, module wiring, public CORS matching, and end-to-end tests for raw query, auth, CRUD, and public read flows. ChangesSitenova microservice feature
Sequence Diagram(s)sequenceDiagram
participant SitenovaSiteController
participant SitenovaRegisterEndUserUseCase
participant SitenovaLoginEndUserUseCase
participant SitenovaEndUserAuthService
SitenovaSiteController->>SitenovaRegisterEndUserUseCase: POST /:connectionId/auth/register
SitenovaRegisterEndUserUseCase->>SitenovaEndUserAuthService: signEndUserToken(connectionId, sub)
SitenovaEndUserAuthService-->>SitenovaRegisterEndUserUseCase: token
SitenovaRegisterEndUserUseCase-->>SitenovaSiteController: token + user
SitenovaSiteController->>SitenovaLoginEndUserUseCase: POST /:connectionId/auth/login
SitenovaLoginEndUserUseCase->>SitenovaEndUserAuthService: signEndUserToken(connectionId, sub)
SitenovaEndUserAuthService-->>SitenovaLoginEndUserUseCase: token
SitenovaLoginEndUserUseCase-->>SitenovaSiteController: token + user
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 3❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Adds a new backend “SiteNova” microservice surface that exposes (1) an internal, microservice-authenticated raw SQL provisioning endpoint and (2) a browser-facing generated-site API for end-user register/login plus data CRUD, along with an AVA e2e test suite and CORS support for the new public routes.
Changes:
- Introduces
SitenovaModulewith internal (/internal/sitenova/...) and public (/sitenova/...) controllers, DTOs, guards, and use cases. - Adds end-user JWT issuance/verification via
SitenovaEndUserAuthService(per-connection signing keys). - Extends the existing wildcard CORS middleware to cover the new SiteNova public API and adds a new e2e test file.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| backend/test/ava-tests/non-saas-tests/non-saas-sitenova-microservice-e2e.test.ts | Adds e2e coverage for internal raw-query auth + public SiteNova auth and CRUD flows. |
| backend/src/middlewares/public-crud-cors.middleware.ts | Extends wildcard CORS handling to include SiteNova public endpoints. |
| backend/src/microservices/sitenova-microservice/use-cases/sitenova-use-cases.interface.ts | Defines the raw-query use case interface contract. |
| backend/src/microservices/sitenova-microservice/use-cases/sitenova-site-use-cases.interface.ts | Defines register/login end-user use case interfaces. |
| backend/src/microservices/sitenova-microservice/use-cases/sitenova-register-enduser.use.case.ts | Implements end-user registration into a connection-scoped users table. |
| backend/src/microservices/sitenova-microservice/use-cases/sitenova-login-enduser.use.case.ts | Implements end-user login with password verification and token minting. |
| backend/src/microservices/sitenova-microservice/use-cases/sitenova-execute-raw-query.use.case.ts | Implements internal write-capable raw SQL execution against a connection. |
| backend/src/microservices/sitenova-microservice/sitenova.module.ts | Wires controllers, guards, services, and use cases; applies microservice auth middleware to internal controller. |
| backend/src/microservices/sitenova-microservice/sitenova-site.controller.ts | Adds the browser-facing SiteNova API: register/login and CRUD endpoints. |
| backend/src/microservices/sitenova-microservice/sitenova-internal.controller.ts | Adds the microservice-authenticated raw-query endpoint for provisioning. |
| backend/src/microservices/sitenova-microservice/services/sitenova-enduser-auth.service.ts | Adds per-connection HS256 token signing/verification for generated-site visitors. |
| backend/src/microservices/sitenova-microservice/guards/sitenova-public-read.guard.ts | Enforces public-read policy (Cedar) for SiteNova read endpoints. |
| backend/src/microservices/sitenova-microservice/guards/sitenova-enduser-auth.guard.ts | Enforces SiteNova end-user JWT for write endpoints. |
| backend/src/microservices/sitenova-microservice/dto/sitenova.dtos.ts | Adds DTOs for internal raw-query requests. |
| backend/src/microservices/sitenova-microservice/dto/sitenova-site.dtos.ts | Adds DTOs for public SiteNova register/login and CRUD payloads. |
| backend/src/microservices/sitenova-microservice/data-structures/sitenova.ds.ts | Adds DS for internal raw-query use case inputs. |
| backend/src/microservices/sitenova-microservice/data-structures/sitenova-site.ds.ts | Adds DS/constants for end-user auth (audience/ttl/payload). |
| backend/src/microservices/sitenova-microservice/data-structures/sitenova-responses.ds.ts | Adds response RO for raw-query results. |
| backend/src/common/data-injection.tokens.ts | Registers new SiteNova use case injection tokens. |
| backend/src/app.module.ts | Registers SitenovaModule in the main application module. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Browser-facing SiteNova site API (register/login + data CRUD) served to AI-generated sites from | ||
| // arbitrary CDN origins. Anchored at the start of the path so it matches `/sitenova/...` but never | ||
| // the server-to-server `/internal/sitenova/...` controller, which needs no CORS. | ||
| const SITENOVA_PUBLIC_ROUTE_REGEX = /^\/sitenova\//; |
| const hashedPassword = await Encryptor.hashUserPassword(password); | ||
| const rowToInsert: Record<string, unknown> = { ...extra, [emailField]: email, [passwordField]: hashedPassword }; | ||
| await dao.addRowInTable(tableName, rowToInsert, userEmail); | ||
|
|
||
| const token = await this.endUserAuthService.signEndUserToken(connectionId, email); | ||
| const user: Record<string, unknown> = { ...extra, [emailField]: email }; | ||
| return { token, user }; |
| const connection = await this._dbContext.connectionRepository.findAndDecryptConnection( | ||
| connectionId, | ||
| masterPassword as string, | ||
| ); |
| const inputData: PureGetRowsDs = { | ||
| connectionId, | ||
| masterPwd: '', | ||
| page: body.page ?? 0, | ||
| perPage: body.perPage ?? 0, | ||
| query: {}, | ||
| searchingFieldValue: body.search ?? '', | ||
| tableName: body.tableName, | ||
| userId: undefined, | ||
| filters: body.filters, | ||
| }; |
| const inputData: PureCreateRowDs = { | ||
| connectionId, | ||
| masterPwd: '', | ||
| row: body.row, | ||
| tableName: body.tableName, | ||
| userId: '', | ||
| }; | ||
| return await this.pureCreateRowInTableUseCase.execute(inputData, InTransactionEnum.OFF); |
| const tableStructure = await dao.getTableStructure(tableName, userEmail); | ||
|
|
||
| const filteringFields = parseFilteringFieldsFromBodyData({ [emailField]: { eq: email } }, tableStructure); | ||
| const settings = buildDAOsTableSettingsDs(buildCommonTableSettingsInput(null), null); | ||
| const found = await dao.getRowsFromTable( | ||
| tableName, | ||
| settings, | ||
| 1, | ||
| 1, |
| const tableStructure = await dao.getTableStructure(tableName, userEmail); | ||
|
|
||
| // Direct, parameterized DAO read (NOT the public column-filtered path) so the hashed password | ||
| // column is available to verify against. The hash is never returned to the caller. | ||
| const filteringFields = parseFilteringFieldsFromBodyData({ [emailField]: { eq: email } }, tableStructure); | ||
| const settings = buildDAOsTableSettingsDs(buildCommonTableSettingsInput(null), null); | ||
| const found = await dao.getRowsFromTable( | ||
| tableName, | ||
| settings, |
Summary by CodeRabbit
New Features
Bug Fixes