127 lines
4.7 KiB
Markdown
127 lines
4.7 KiB
Markdown
# Registration Service
|
|
|
|
ASP.NET Core (.NET 8) service for managing prospect registration in AdPlatform.
|
|
Self-hosted via docker-compose as `registration:8080` behind nginx / Gateway.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
Client SPA (client.positivespend.com)
|
|
└─► Gateway (portal.positivespend.com)
|
|
└─► Registration API (regapi.positivespend.com → registration:8080)
|
|
├─► dbRegistration (10.10.99.212 — Registrations table, spRegistration)
|
|
└─► CIAM (PositiveSpendClients.ciamlogin.com — token validation)
|
|
|
|
Management API (mgmt.positivespend.com)
|
|
└─► Registration API (admin endpoints, x-functions-key auth)
|
|
└─► dbRegistration
|
|
```
|
|
|
|
The Registration service never touches `dbAdPlatform`. Management never touches `dbRegistration`.
|
|
Approval provisioning into `dbAdPlatform` is the Management API's responsibility, called after
|
|
the `complete` action marks a registration as Approved.
|
|
|
|
## Endpoints
|
|
|
|
| Method | Route | Auth | Description |
|
|
|--------|-------|------|-------------|
|
|
| `POST` | `/api/registration/register` | Bearer (CIAM JWT) | New prospect signup |
|
|
| `GET` | `/api/registration/pending` | x-functions-key | List pending applicants |
|
|
| `GET` | `/api/registration/item/{id}` | x-functions-key | Get single applicant |
|
|
| `POST` | `/api/registration/action/{id}/reject` | x-functions-key | Reject applicant |
|
|
| `POST` | `/api/registration/action/{id}/complete` | x-functions-key | Mark approved |
|
|
| `GET` | `/api/health` | Anonymous | Health check |
|
|
|
|
`entraSubjectId` is **never** read from the request body on `/register` — it is extracted
|
|
from the validated CIAM Bearer token (OID claim). The client cannot spoof it.
|
|
|
|
## Authentication
|
|
|
|
**Client-facing endpoint** (`/register`): Bearer token issued by
|
|
`PositiveSpendClients.ciamlogin.com` (tenant `cbf8b7d7`). Validated by
|
|
`Microsoft.Identity.Web` against the CIAM tenant. The Client SPA acquires this
|
|
token via MSAL after the user signs in with Google, Apple, or Microsoft.
|
|
|
|
**Admin endpoints** (`pending` / `item` / `reject` / `complete`): `x-functions-key` header
|
|
validated by `ApiKeyAuthFilter`. Key must match `Registration__FunctionKey` env var.
|
|
These endpoints are called by the Management API, not the browser.
|
|
|
|
## CIAM Tenant Reference
|
|
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| Tenant | Positive Spend Clients |
|
|
| Tenant ID | `cbf8b7d7-1e13-486d-b5b0-287ba79fdf0b` |
|
|
| Client SPA App ID | `c426967f-bfcc-46af-b4e5-d69dc01cbf75` |
|
|
| Authority | `https://PositiveSpendClients.ciamlogin.com/cbf8b7d7.../` |
|
|
|
|
This is the **client-facing CIAM tenant** — separate from the internal `positivespend.com`
|
|
org tenant (`f56a3c51`) used by Management and the Tech/Admin consoles.
|
|
|
|
## Mock Mode
|
|
|
|
Switch in `Program.cs` to run without a database (seeds 4 test applicants in memory):
|
|
|
|
```csharp
|
|
services.AddSingleton<IRegistrationDataService, MockDataService>();
|
|
```
|
|
|
|
State resets on container restart — by design.
|
|
|
|
## Database Setup
|
|
|
|
Run `dbo.spRegistration.sql` against `dbRegistration` on `10.10.99.212` once.
|
|
It is idempotent (`CREATE OR ALTER PROCEDURE`, `IF OBJECT_ID ... IS NULL` guard on the table).
|
|
|
|
## docker-compose Environment Variables
|
|
|
|
```bash
|
|
# SQL Server
|
|
ConnectionStrings__Sql=Server=10.10.99.212;Database=dbRegistration;User Id=appAdPlatformReg;Password=...;TrustServerCertificate=True;
|
|
|
|
# CIAM — already correct in .env
|
|
AzureAd__Instance=https://PositiveSpendClients.ciamlogin.com/
|
|
AzureAd__TenantId=cbf8b7d7-1e13-486d-b5b0-287ba79fdf0b
|
|
AzureAd__ClientId=c426967f-bfcc-46af-b4e5-d69dc01cbf75
|
|
|
|
# CORS — already in .env
|
|
CORS__AllowedOrigins=https://client.positivespend.com,https://portal.positivespend.com,...
|
|
|
|
# Admin key — already in .env
|
|
Registration__FunctionKey=mra0B2boC5m36E7CUn-Urhwp7k3t3QvPZKjJvtNVEdVgAzFuuaAyRA==
|
|
```
|
|
|
|
## Health Check
|
|
|
|
```bash
|
|
curl https://regapi.positivespend.com/api/health
|
|
# {"ok":true,"service":"registration","mode":"database","timestamp":"..."}
|
|
```
|
|
|
|
## SSL
|
|
|
|
```bash
|
|
sudo certbot --nginx -d regapi.positivespend.com
|
|
```
|
|
|
|
---
|
|
|
|
## Host Swap — Restore Azure Functions
|
|
|
|
Three files change. Everything else (Data layer, Mock layer, models, SQL) is identical.
|
|
|
|
| File | Change |
|
|
|------|--------|
|
|
| `Registration.csproj` | Comment ASP.NET Core `ItemGroup`, uncomment Functions `ItemGroup`, restore `<AzureFunctionsVersion>v4</AzureFunctionsVersion>`, change `Sdk` to `Microsoft.NET.Sdk` |
|
|
| `Program.cs` | Comment ASP.NET Core block, uncomment Functions `HostBuilder` block |
|
|
| `Functions/RegistrationFunctions.cs` | Swap class declaration, swap each method signature (all marked `◄ INACTIVE`) |
|
|
|
|
Client changes when restoring Functions:
|
|
- `authConfig.js`: set `API_BASE_URL` to the Azure Function App URL, set `API_FUNCTION_KEY` from Azure Portal → App Keys → default
|
|
|
|
Run locally in Functions mode:
|
|
```bash
|
|
func start
|
|
curl http://localhost:7071/api/health
|
|
```
|