clean routes

This commit is contained in:
2026-01-03 02:42:47 +01:00
parent 07985fb8f1
commit 2f21dc4595
107 changed files with 7596 additions and 3401 deletions

View File

@@ -1,5 +1,6 @@
import { Module } from '@nestjs/common';
import { IdentityPersistenceModule } from '../../persistence/identity/IdentityPersistenceModule';
import { InMemoryAdminPersistenceModule } from '../../persistence/inmemory/InMemoryAdminPersistenceModule';
import { AuthService } from './AuthService';
import { AuthController } from './AuthController';
import { AuthProviders } from './AuthProviders';
@@ -8,7 +9,7 @@ import { AuthorizationGuard } from './AuthorizationGuard';
import { AuthorizationService } from './AuthorizationService';
@Module({
imports: [IdentityPersistenceModule],
imports: [IdentityPersistenceModule, InMemoryAdminPersistenceModule],
controllers: [AuthController],
providers: [AuthService, ...AuthProviders, AuthenticationGuard, AuthorizationService, AuthorizationGuard],
exports: [AuthService, AuthenticationGuard, AuthorizationService, AuthorizationGuard],

View File

@@ -19,6 +19,7 @@ import type { ForgotPasswordResult } from '@core/identity/application/use-cases/
import type { ResetPasswordResult } from '@core/identity/application/use-cases/ResetPasswordUseCase';
import type { DemoLoginResult } from '../../development/use-cases/DemoLoginUseCase';
import type { Logger, UseCaseOutputPort } from '@core/shared/application';
import type { IAdminUserRepository } from '@core/admin/domain/repositories/IAdminUserRepository';
import {
AUTH_REPOSITORY_TOKEN,
@@ -26,6 +27,7 @@ import {
USER_REPOSITORY_TOKEN,
MAGIC_LINK_REPOSITORY_TOKEN,
} from '../../persistence/identity/IdentityPersistenceTokens';
import { ADMIN_USER_REPOSITORY_TOKEN } from '../../persistence/admin/AdminPersistenceTokens';
import { AuthSessionPresenter } from './presenters/AuthSessionPresenter';
import { CommandResultPresenter } from './presenters/CommandResultPresenter';
@@ -143,7 +145,8 @@ export const AuthProviders: Provider[] = [
passwordHashing: IPasswordHashingService,
logger: Logger,
output: UseCaseOutputPort<DemoLoginResult>,
) => new DemoLoginUseCase(authRepo, passwordHashing, logger, output),
inject: [AUTH_REPOSITORY_TOKEN, PASSWORD_HASHING_SERVICE_TOKEN, LOGGER_TOKEN, DEMO_LOGIN_OUTPUT_PORT_TOKEN],
adminUserRepo: IAdminUserRepository,
) => new DemoLoginUseCase(authRepo, passwordHashing, logger, output, adminUserRepo),
inject: [AUTH_REPOSITORY_TOKEN, PASSWORD_HASHING_SERVICE_TOKEN, LOGGER_TOKEN, DEMO_LOGIN_OUTPUT_PORT_TOKEN, ADMIN_USER_REPOSITORY_TOKEN],
},
];

View File

@@ -225,6 +225,7 @@ describe('AuthService - New Methods', () => {
userId: 'demo-user-123',
email: 'demo.driver@example.com',
displayName: 'Alex Johnson',
role: 'driver',
},
});
});

View File

@@ -89,13 +89,13 @@ export class AuthService {
const coreSession = await this.identitySessionPort.getCurrentSession();
if (!coreSession) return null;
// TODO!!
return {
token: coreSession.token,
user: {
userId: coreSession.user.id,
email: coreSession.user.email ?? '',
displayName: coreSession.user.displayName,
role: coreSession.user.role as any,
},
};
}
@@ -307,6 +307,7 @@ export class AuthService {
id: sessionId,
displayName: user.getDisplayName(),
email: user.getEmail() ?? '',
role: params.role,
},
sessionOptions
);
@@ -315,6 +316,7 @@ export class AuthService {
userId: user.getId().value,
email: user.getEmail() ?? '',
displayName: user.getDisplayName(),
role: params.role,
};
if (primaryDriverId !== undefined) {
@@ -326,4 +328,4 @@ export class AuthService {
user: userDTO,
};
}
}
}

View File

@@ -3,7 +3,7 @@ import type { IdentitySessionPort } from '@core/identity/application/ports/Ident
import { IDENTITY_SESSION_PORT_TOKEN } from './AuthProviders';
type AuthenticatedRequest = {
user?: { userId: string };
user?: { userId: string; role?: string | undefined };
};
@Injectable()
@@ -22,7 +22,10 @@ export class AuthenticationGuard implements CanActivate {
const session = await this.sessionPort.getCurrentSession();
if (session?.user?.id) {
request.user = { userId: session.user.id };
request.user = {
userId: session.user.id,
role: session.user.role
};
}
return true;

View File

@@ -6,7 +6,7 @@ import { REQUIRE_AUTHENTICATED_USER_METADATA_KEY } from './RequireAuthenticatedU
import { REQUIRE_ROLES_METADATA_KEY, RequireRolesMetadata } from './RequireRoles';
type AuthenticatedRequest = {
user?: { userId: string };
user?: { userId: string; role?: string | undefined };
};
@Injectable()
@@ -16,7 +16,7 @@ export class AuthorizationGuard implements CanActivate {
private readonly authorizationService: AuthorizationService,
) {}
canActivate(context: ExecutionContext): boolean {
async canActivate(context: ExecutionContext): Promise<boolean> {
const handler = context.getHandler();
const controllerClass = context.getClass();
@@ -55,8 +55,24 @@ export class AuthorizationGuard implements CanActivate {
void requiresAuth;
if (rolesMetadata && rolesMetadata.anyOf.length > 0) {
const userRoles = this.authorizationService.getRolesForUser(userId);
const hasAnyRole = rolesMetadata.anyOf.some((r) => userRoles.includes(r));
let userRoles = this.authorizationService.getRolesForUser(userId);
// If no roles from service, check request for demo login roles
if (userRoles.length === 0 && request.user?.role) {
userRoles = [request.user.role];
}
// Map demo login roles to API expected roles
const mappedRoles = userRoles.map(role => {
if (role === 'league-admin') return 'admin';
if (role === 'league-owner') return 'owner';
if (role === 'league-steward') return 'steward';
if (role === 'system-owner') return 'owner';
if (role === 'super-admin') return 'admin';
return role;
});
const hasAnyRole = rolesMetadata.anyOf.some((r) => mappedRoles.includes(r));
if (!hasAnyRole) {
throw new ForbiddenException('Forbidden');
}

View File

@@ -3,10 +3,11 @@ import { getHttpRequestContext } from '@adapters/http/RequestContext';
export type Actor = {
userId: string;
driverId: string;
role?: string | undefined;
};
type AuthenticatedRequest = {
user?: { userId: string };
user?: { userId: string; role?: string };
};
export function getActorFromRequestContext(): Actor {
@@ -21,5 +22,6 @@ export function getActorFromRequestContext(): Actor {
// Current canonical mapping:
// - The authenticated session identity is `userId`.
// - In the current system, that `userId` is also treated as the performer `driverId`.
return { userId, driverId: userId };
// - Include role from session if available
return { userId, driverId: userId, role: req.user?.role };
}