feat(#87): implement cross-instance identity linking for federation
Implements FED-004: Cross-Instance Identity Linking, building on the foundation from FED-001, FED-002, and FED-003. New Services: - IdentityLinkingService: Handles identity verification and mapping with signature validation and OIDC token verification - IdentityResolutionService: Resolves identities between local and remote instances with support for bulk operations New API Endpoints (IdentityLinkingController): - POST /api/v1/federation/identity/verify - Verify remote identity - POST /api/v1/federation/identity/resolve - Resolve remote to local user - POST /api/v1/federation/identity/bulk-resolve - Bulk resolution - GET /api/v1/federation/identity/me - Get current user's identities - POST /api/v1/federation/identity/link - Create identity mapping - PATCH /api/v1/federation/identity/:id - Update mapping - DELETE /api/v1/federation/identity/:id - Revoke mapping - GET /api/v1/federation/identity/:id/validate - Validate mapping Security Features: - Signature verification using remote instance public keys - OIDC token validation before creating mappings - Timestamp validation to prevent replay attacks - Workspace isolation via authentication guards - Comprehensive audit logging for all identity operations Enhancements: - Added SignatureService.verifyMessage() for remote signature verification - Added FederationService.getConnectionByRemoteInstanceId() - Extended FederationAuditService with identity logging methods - Created comprehensive DTOs with class-validator decorators Testing: - 38 new tests (19 service + 7 resolution + 12 controller) - All 132 federation tests passing - TypeScript compilation passing with no errors - High test coverage achieved (>85% requirement exceeded) Technical Details: - Leverages existing FederatedIdentity model from FED-003 - Uses RSA SHA-256 signatures for cryptographic verification - Supports one identity mapping per remote instance per user - Resolution service optimized for read-heavy operations - Built following TDD principles (Red-Green-Refactor) Closes #87 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
98
apps/api/src/federation/dto/identity-linking.dto.ts
Normal file
98
apps/api/src/federation/dto/identity-linking.dto.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Identity Linking DTOs
|
||||
*
|
||||
* Data transfer objects for identity linking API endpoints.
|
||||
*/
|
||||
|
||||
import { IsString, IsEmail, IsOptional, IsObject, IsArray, IsNumber } from "class-validator";
|
||||
|
||||
/**
|
||||
* DTO for verifying identity from remote instance
|
||||
*/
|
||||
export class VerifyIdentityDto {
|
||||
@IsString()
|
||||
localUserId!: string;
|
||||
|
||||
@IsString()
|
||||
remoteUserId!: string;
|
||||
|
||||
@IsString()
|
||||
remoteInstanceId!: string;
|
||||
|
||||
@IsString()
|
||||
oidcToken!: string;
|
||||
|
||||
@IsNumber()
|
||||
timestamp!: number;
|
||||
|
||||
@IsString()
|
||||
signature!: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* DTO for resolving remote user to local user
|
||||
*/
|
||||
export class ResolveIdentityDto {
|
||||
@IsString()
|
||||
remoteInstanceId!: string;
|
||||
|
||||
@IsString()
|
||||
remoteUserId!: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* DTO for reverse resolving local user to remote identity
|
||||
*/
|
||||
export class ReverseResolveIdentityDto {
|
||||
@IsString()
|
||||
localUserId!: string;
|
||||
|
||||
@IsString()
|
||||
remoteInstanceId!: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* DTO for bulk identity resolution
|
||||
*/
|
||||
export class BulkResolveIdentityDto {
|
||||
@IsString()
|
||||
remoteInstanceId!: string;
|
||||
|
||||
@IsArray()
|
||||
@IsString({ each: true })
|
||||
remoteUserIds!: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* DTO for creating identity mapping
|
||||
*/
|
||||
export class CreateIdentityMappingDto {
|
||||
@IsString()
|
||||
remoteInstanceId!: string;
|
||||
|
||||
@IsString()
|
||||
remoteUserId!: string;
|
||||
|
||||
@IsString()
|
||||
oidcSubject!: string;
|
||||
|
||||
@IsEmail()
|
||||
email!: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
metadata?: Record<string, unknown>;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
oidcToken?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* DTO for updating identity mapping
|
||||
*/
|
||||
export class UpdateIdentityMappingDto {
|
||||
@IsOptional()
|
||||
@IsObject()
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
Reference in New Issue
Block a user