chore(LOY-445): remove ENABLE_DTMC flag & add documentation * chore(LOY-445): remove ENABLE_DTMC flag & add documentation Approved-by: Matilda Landström
7.0 KiB
7.0 KiB
DTMC (Digital Team Member Card) Flow Documentation
Overview
The DTMC feature allows existing Scandic Friends members to link their employee status to their account by authenticating with Microsoft Entra ID. This provides employees access to additional benefits.
Current Implementation Architecture
Separate Auth Configuration Approach
We use a completely separate auth configuration to avoid session conflicts between:
- Curity:
auth.ts- Regular user authentication.
- DTMC Auth:
auth.dtmc.ts- Short-lived (10min) session specifically for employee verification.
Key Files & Responsibilities
Flow Handlers
app/[lang]/(live)/(public)/dtmc/route.ts- Microsoft auth initiation.
app/api/web/auth/dtmc/route.ts- Employee linking callback handler with API integration.
Core Authentication
auth.dtmc.ts- Microsoft Entra ID provider configuration, JWT/session callbacks.
app/api/web/auth/[...nextauth]/route.ts- Routes Microsoft requests to DTMC handlers.
API Integration
packages/trpc/lib/api/endpoints.ts- API endpoint definitions including TeamMemberCard.
server/routers/user/output.ts- Profile schema with employmentDetails.
utils/user.ts- Employment utility functions.
UI Components
apps/scandic-web/components/MyPages/DigitalTeamMemberCard/index.tsx- Main card component.
apps/scandic-web/components/MyPages/DigitalTeamMemberCard/Alert/index.tsx- Banner shown on the overview page for employee's who have just linked their account.
Configuration
constants/routes/dtmc.ts- Route definitionscomponents/DigitalTeamMemberCard/EmployeeBenefits/CallToActions/index.tsx- "Link Employment" buttons used within the Employee Benefits page (a Contentstack "content page") to initiate the linking process.
Technical Flow
1. User Journey
User (Curity authenticated) → Employee Benefits page → "Link Employment" button →
Microsoft Auth → Employee ID extraction → API linking → Success redirect
2. Detailed Technical Sequence
sequenceDiagram
participant U as User
participant C as Curity Session
participant D as DTMC Route
participant M as Microsoft Auth
participant J as JWT Callback
participant S as Session Callback
participant H as DTMC Handler
participant A as Employee API
U->>C: Already authenticated (Curity)
U->>D: Click "Link Employment" → /[lang]/dtmc
D->>M: signIn("microsoft-entra-id")
M->>U: Microsoft login prompt
U->>M: Authenticate with corporate credentials
M->>J: Profile with user.employeeid
J->>J: Store employeeId directly in token
J->>S: Expose as session.employeeId
S->>H: Callback to /api/web/auth/dtmc
H->>H: Validate both Curity + DTMC sessions
H->>A: Call linkEmployeeToUser(employeeId)
A->>H: Success response
H->>U: Redirect to overview with success banner
3. Code Implementation Details
DTMC Auth Configuration (auth.dtmc.ts)
// Separate session cookie to avoid conflicts
cookies: {
sessionToken: {
name: "dtmc.session-token",
},
}
// Short-lived session for security
session: {
strategy: "jwt",
maxAge: 10 * 60, // 10 minutes
}
// Storage of employeeId
jwt({ account, profile, token }) {
if (account?.provider === "microsoft-entra-id") {
const employeeId = profile["user.employeeid"]
return {
access_token: "", // Empty to save cookie size
loginType: "dtmc",
employeeId,
}
}
}
Route Routing ([...nextauth]/route.ts)
Routes Microsoft requests to DTMC handlers by checking if the pathname contains "microsoft-entra-id".
Auth Initiation (/dtmc/route.ts)
// Starts Microsoft signin with callback redirect
const redirectUrl = await signIn(
"microsoft-entra-id",
{
redirectTo: `${env.PUBLIC_URL}${dtmcApiCallback}`,
redirect: false,
},
{
prompt: "login",
}
)
Callback Handler (/api/web/auth/dtmc/route.ts)
// Validates dual sessions and processes linking
const dtmcSession = await dtmcAuth() // Microsoft session
const session = await auth() // Curity session
// Both sessions required for security
if (!isValidSession(session) || !isValidSession(dtmcSession)) {
// Redirect to error page
}
const employeeId = dtmcSession.employeeId
await linkEmployeeToUser(employeeId, accessToken)
Routes & URLs
User-Facing Routes
/[lang]/dtmc- Microsoft auth initiation/[lang]/link-employment-error- Error handling page/[lang]/employee-benefits- Employee benefits overview
API Routes
/api/web/auth/dtmc- Employee linking callback handler/api/web/auth/[...nextauth]- NextAuth routing (handles Microsoft provider)
API Integration Details
TeamMemberCard Endpoint
// Added to packages/trpc/lib/api/endpoints.ts
export namespace v2 {
export namespace Profile {
export function teamMemberCard(employeeId: string) {
return `${profile}/${employeeId}/TeamMemberCard`
}
}
}
Profile Schema Extension
// Added to server/routers/user/output.ts
export const employmentDetailsSchema = z
.object({
employeeId: z.string(),
location: z.string(),
country: z.string(),
retired: z.boolean(),
})
.optional()
Employee Utility Functions
// Added to utils/user.ts
export function isEmployeeLinked(user: User): boolean
export function getEmployeeInfo(user: User)
export function canUseEmployeeBenefits(user: User): boolean
Status Code Handling
- 200/202: Success → Continue to overview page
- 400/404: Client errors → "unable_to_verify_employee_id" error page
- 500: Server error → Default error message
- Network errors: → Default error message
Digital Team Member Card Behavior
// Current implementation
const hasEmploymentData = isEmployeeLinked(user)
if (!hasEmploymentData) {
return null
}
return <DigitalTeamMemberCardClient user={user} />
Testing Checklist
Happy Path
- User has valid Curity session
- Microsoft auth extracts employee ID successfully
- Both sessions validated in callback handler
- Employee linking API call succeeds
- User redirected to overview with success banner
- Original Curity session remains functional
- Digital Team Member Card displays with employment data
Error Scenarios
- Missing Curity session during flow
- Microsoft auth failure/cancellation
- Missing employee ID in Microsoft profile
- Employee API failure scenarios
- DTMC session expiration
- Status code mapping (400/404/500/network errors)
Security Validation
- No employee ID in browser network logs
- No employee ID in URL parameters
- Dual session architecture working
- Proper session validation in callback
- Short-lived DTMC session (10 minutes) for security
UI/UX Validation
- Card shows real data when employment details exist
- Proper fallbacks for missing employment data fields