diff --git a/apps/server/src/modules/authentication/controllers/api-test/login.api.spec.ts b/apps/server/src/modules/authentication/controllers/api-test/login.api.spec.ts index 7da3c21eab9..e9e8a30dd2e 100644 --- a/apps/server/src/modules/authentication/controllers/api-test/login.api.spec.ts +++ b/apps/server/src/modules/authentication/controllers/api-test/login.api.spec.ts @@ -287,7 +287,7 @@ describe('Login Controller (api)', () => { roles: [studentRole.id], schoolId: school.id, accountId: account.id, - isExternalUser: false, + isExternalUser: true, }); expect(decodedToken).not.toHaveProperty('externalIdToken'); }); diff --git a/apps/server/src/modules/authentication/controllers/login.controller.ts b/apps/server/src/modules/authentication/controllers/login.controller.ts index 68af396233e..00f9c0f7bc8 100644 --- a/apps/server/src/modules/authentication/controllers/login.controller.ts +++ b/apps/server/src/modules/authentication/controllers/login.controller.ts @@ -3,7 +3,7 @@ import { AuthGuard } from '@nestjs/passport'; import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { ForbiddenOperationError, ValidationError } from '@shared/common'; import { CurrentUser } from '../decorator'; -import type { ICurrentUser, OauthCurrentUser } from '../interface'; +import type { ICurrentUser, LdapCurrentUser, OauthCurrentUser } from '../interface'; import { LoginDto } from '../uc/dto'; import { LoginUc } from '../uc/login.uc'; import { @@ -27,8 +27,11 @@ export class LoginController { @ApiResponse({ status: 200, type: LoginResponse, description: 'Login was successful.' }) @ApiResponse({ status: 400, type: ValidationError, description: 'Request data has invalid format.' }) @ApiResponse({ status: 403, type: ForbiddenOperationError, description: 'Invalid user credentials.' }) - // eslint-disable-next-line @typescript-eslint/no-unused-vars - async loginLdap(@CurrentUser() user: ICurrentUser, @Body() _: LdapAuthorizationBodyParams): Promise { + async loginLdap( + @CurrentUser() user: LdapCurrentUser, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + @Body() _: LdapAuthorizationBodyParams + ): Promise { const loginDto: LoginDto = await this.loginUc.getLoginData(user); const mapped: LoginResponse = LoginResponseMapper.mapToLoginResponse(loginDto); diff --git a/apps/server/src/modules/authentication/interface/index.ts b/apps/server/src/modules/authentication/interface/index.ts index e5abc856509..857059841c4 100644 --- a/apps/server/src/modules/authentication/interface/index.ts +++ b/apps/server/src/modules/authentication/interface/index.ts @@ -1 +1,3 @@ export * from './user'; +export * from './ldap-current-user'; +export * from './oauth-current-user'; diff --git a/apps/server/src/modules/authentication/interface/ldap-current-user.ts b/apps/server/src/modules/authentication/interface/ldap-current-user.ts new file mode 100644 index 00000000000..4f9991314d4 --- /dev/null +++ b/apps/server/src/modules/authentication/interface/ldap-current-user.ts @@ -0,0 +1,3 @@ +import { ICurrentUser } from './user'; + +export interface LdapCurrentUser extends ICurrentUser {} diff --git a/apps/server/src/modules/authentication/interface/oauth-current-user.ts b/apps/server/src/modules/authentication/interface/oauth-current-user.ts new file mode 100644 index 00000000000..ddf15e1ca5d --- /dev/null +++ b/apps/server/src/modules/authentication/interface/oauth-current-user.ts @@ -0,0 +1,6 @@ +import { ICurrentUser } from './user'; + +export interface OauthCurrentUser extends ICurrentUser { + /** Contains the idToken of the external idp. Will be set during oAuth2 login and used for rp initiated logout */ + externalIdToken?: string; +} diff --git a/apps/server/src/modules/authentication/interface/user.ts b/apps/server/src/modules/authentication/interface/user.ts index cc8423f69b7..82b6d292d50 100644 --- a/apps/server/src/modules/authentication/interface/user.ts +++ b/apps/server/src/modules/authentication/interface/user.ts @@ -16,11 +16,6 @@ export interface ICurrentUser { /** True if a support member impersonates the user */ impersonated?: boolean; - /** True if the user is an external user e.g. an oauth user */ + /** True if the user is an external user e.g. an oauth user or ldap user */ isExternalUser: boolean; } - -export interface OauthCurrentUser extends ICurrentUser { - /** Contains the idToken of the external idp. Will be set during oAuth2 login and used for rp initiated logout */ - externalIdToken?: string; -} diff --git a/apps/server/src/modules/authentication/mapper/current-user.mapper.spec.ts b/apps/server/src/modules/authentication/mapper/current-user.mapper.spec.ts index d06bea6d080..2b2f8e6fbb5 100644 --- a/apps/server/src/modules/authentication/mapper/current-user.mapper.spec.ts +++ b/apps/server/src/modules/authentication/mapper/current-user.mapper.spec.ts @@ -304,4 +304,33 @@ describe('CurrentUserMapper', () => { }); }); }); + + describe('mapToLdapCurrentUser', () => { + const setup = () => { + const user = userFactory.buildWithId({ + school: schoolFactory.buildWithId(), + }); + const systemId = 'mockSystemId'; + + return { + user, + systemId, + }; + }; + + it('should map to ldap current user', () => { + const { user, systemId } = setup(); + + const currentUser: ICurrentUser = CurrentUserMapper.mapToLdapCurrentUser(accountId, user, systemId); + + expect(currentUser).toMatchObject({ + accountId, + systemId, + roles: [], + schoolId: user.school.id, + userId: user.id, + isExternalUser: true, + }); + }); + }); }); diff --git a/apps/server/src/modules/authentication/mapper/current-user.mapper.ts b/apps/server/src/modules/authentication/mapper/current-user.mapper.ts index ab832b70d8c..5e2baafd5d3 100644 --- a/apps/server/src/modules/authentication/mapper/current-user.mapper.ts +++ b/apps/server/src/modules/authentication/mapper/current-user.mapper.ts @@ -2,7 +2,7 @@ import { ValidationError } from '@shared/common'; import { Role, User } from '@shared/domain'; import { RoleReference } from '@shared/domain/domainobject'; import { UserDO } from '@shared/domain/domainobject/user.do'; -import { ICurrentUser, OauthCurrentUser } from '../interface'; +import { ICurrentUser, LdapCurrentUser, OauthCurrentUser } from '../interface'; import { CreateJwtPayload, JwtPayload } from '../interface/jwt-payload'; export class CurrentUserMapper { @@ -17,6 +17,10 @@ export class CurrentUserMapper { }; } + static mapToLdapCurrentUser(accountId: string, user: User, systemId?: string): LdapCurrentUser { + return { ...CurrentUserMapper.userToICurrentUser(accountId, user, systemId), isExternalUser: true }; + } + static mapToOauthCurrentUser( accountId: string, user: UserDO, diff --git a/apps/server/src/modules/authentication/strategy/ldap.strategy.spec.ts b/apps/server/src/modules/authentication/strategy/ldap.strategy.spec.ts index 78f445ce5b0..5b23be9eb74 100644 --- a/apps/server/src/modules/authentication/strategy/ldap.strategy.spec.ts +++ b/apps/server/src/modules/authentication/strategy/ldap.strategy.spec.ts @@ -436,7 +436,7 @@ describe('LdapStrategy', () => { schoolId: school.id, systemId: system.id, accountId: account.id, - isExternalUser: false, + isExternalUser: true, }); }); }); @@ -501,7 +501,7 @@ describe('LdapStrategy', () => { schoolId: school.id, systemId: system.id, accountId: account.id, - isExternalUser: false, + isExternalUser: true, }); }); }); diff --git a/apps/server/src/modules/authentication/strategy/ldap.strategy.ts b/apps/server/src/modules/authentication/strategy/ldap.strategy.ts index 1622e434310..02f34fff36b 100644 --- a/apps/server/src/modules/authentication/strategy/ldap.strategy.ts +++ b/apps/server/src/modules/authentication/strategy/ldap.strategy.ts @@ -7,7 +7,7 @@ import { Logger } from '@src/core/logger'; import { AccountDto } from '@modules/account/services/dto'; import { Strategy } from 'passport-custom'; import { LdapAuthorizationBodyParams } from '../controllers/dto'; -import { ICurrentUser } from '../interface'; +import { ICurrentUser, LdapCurrentUser } from '../interface'; import { CurrentUserMapper } from '../mapper'; import { AuthenticationService } from '../services/authentication.service'; import { LdapService } from '../services/ldap.service'; @@ -48,7 +48,7 @@ export class LdapStrategy extends PassportStrategy(Strategy, 'ldap') { await this.checkCredentials(account, system, ldapDn, password); - const currentUser: ICurrentUser = CurrentUserMapper.userToICurrentUser(account.id, user, systemId); + const currentUser: LdapCurrentUser = CurrentUserMapper.mapToLdapCurrentUser(account.id, user, systemId); return currentUser; }