1- import { Injectable , HttpException , HttpStatus } from '@nestjs/common' ;
2- import { CreateUserDto } from './dto/user-create.dto' ;
3- import { UserLoginResponseDto } from './dto/user-login-response.dto' ;
4- import { PrismaService } from '../prisma/prisma.service' ;
1+ import { HttpException , HttpStatus } from '@nestjs/common' ;
2+ import { CreateUserDto } from '.. /dto/user-create.dto' ;
3+ import { UserLoginResponseDto } from '.. /dto/user-login-response.dto' ;
4+ import { PrismaService } from '../../ prisma/prisma.service' ;
55import { Role , User } from '@prisma/client' ;
6- import { UserDto } from './dto/user.dto' ;
7- import { UpdateUserDto } from './dto/user-update.dto' ;
8- import { AuthService } from '../auth/auth.service' ;
9- import { UserLoginRequestDto } from './dto/user-login-request.dto' ;
10- import { AssignRoleDto } from './dto/assign-role.dto' ;
6+ import { UpdateUserDto } from '../dto/user-update.dto' ;
7+ import { AuthService } from '../../auth/auth.service' ;
8+ import { UserLoginRequestDto } from '../dto/user-login-request.dto' ;
119import { Logger } from '@nestjs/common' ;
1210import { Entry as LdapEntry , Client as LdapClient } from 'ldapts' ;
13- import { UsersService } from './users.service' ;
14-
15- @Injectable ( )
16- export class LdapUsersService implements UsersService {
11+ import { Users } from '../users.interface' ;
12+ import { ConfigService } from '@nestjs/config' ;
13+
14+ type LDAPConfig = {
15+ url : string ;
16+ bindUser : string ;
17+ bindPassword : string ;
18+ searchDN : string ;
19+ usersSearchFilter : string ;
20+ attributeMail : string ;
21+ attributeFirstName : string ;
22+ attributeLastName : string ;
23+ tlsNoVerify : boolean ;
24+ } ;
25+ export class LdapUsersService implements Users {
1726 private readonly ldapClient : LdapClient ;
1827 private readonly logger : Logger = new Logger ( LdapUsersService . name ) ;
19- private readonly assertRequiredEnvVarsAreSet = ( ) => {
20- const requiredEnvVars = [
21- 'LDAP_URL' ,
22- 'LDAP_BIND_USER' ,
23- 'LDAP_BIND_PASSWORD' ,
24- 'LDAP_SEARCH_DN' ,
25- 'LDAP_USERS_SEARCH_FILTER' ,
26- 'LDAP_ATTRIBUTE_MAIL' ,
27- 'LDAP_ATTRIBUTE_FIRST_NAME' ,
28- 'LDAP_ATTRIBUTE_LAST_NAME' ,
29- ] ;
30-
31- for ( const envVar of requiredEnvVars ) {
32- if ( ! process . env [ envVar ] ) {
33- throw new Error ( `${ envVar } is required.` ) ;
34- }
35- }
36- } ;
28+ private readonly ldapConfig : LDAPConfig ;
3729
3830 constructor (
31+ private configService : ConfigService ,
3932 private prismaService : PrismaService ,
4033 private authService : AuthService
4134 ) {
42- this . assertRequiredEnvVarsAreSet ( ) ;
35+ this . ldapConfig = {
36+ url : this . configService . getOrThrow < string > ( 'LDAP_URL' ) ,
37+ bindUser : this . configService . getOrThrow < string > ( 'LDAP_BIND_USER' ) ,
38+ bindPassword : this . configService . getOrThrow < string > ( 'LDAP_BIND_PASSWORD' ) ,
39+ searchDN : this . configService . getOrThrow < string > ( 'LDAP_SEARCH_DN' ) ,
40+ usersSearchFilter : this . configService . getOrThrow < string > ( 'LDAP_USERS_SEARCH_FILTER' ) ,
41+ attributeMail : this . configService . getOrThrow < string > ( 'LDAP_ATTRIBUTE_MAIL' ) ,
42+ attributeFirstName : this . configService . getOrThrow < string > ( 'LDAP_ATTRIBUTE_FIRST_NAME' ) ,
43+ attributeLastName : this . configService . getOrThrow < string > ( 'LDAP_ATTRIBUTE_LAST_NAME' ) ,
44+ tlsNoVerify : this . configService . get < boolean > ( 'LDAP_TLS_NO_VERIFY' , false ) ,
45+ } ;
4346 this . ldapClient = new LdapClient ( {
44- url : process . env . LDAP_URL ,
47+ url : this . ldapConfig . url ,
4548 tlsOptions : {
46- rejectUnauthorized : process . env . LDAP_TLS_NO_VERIFY !== 'true' ,
49+ rejectUnauthorized : ! this . ldapConfig . tlsNoVerify ,
4750 } ,
4851 } ) ;
4952 }
@@ -53,16 +56,16 @@ export class LdapUsersService implements UsersService {
5356 email = this . escapeLdap ( email . trim ( ) ) ;
5457 this . logger . verbose ( `search '${ email } ' in LDAP` ) ;
5558 try {
56- await this . ldapClient . bind ( process . env . LDAP_BIND_USER , process . env . LDAP_BIND_PASSWORD ) ;
59+ await this . ldapClient . bind ( this . ldapConfig . bindUser , this . ldapConfig . bindPassword ) ;
5760 const attributes = [
5861 'dn' ,
59- process . env . LDAP_ATTRIBUTE_MAIL ,
60- process . env . LDAP_ATTRIBUTE_FIRST_NAME ,
61- process . env . LDAP_ATTRIBUTE_LAST_NAME ,
62+ this . ldapConfig . attributeMail ,
63+ this . ldapConfig . attributeFirstName ,
64+ this . ldapConfig . attributeLastName ,
6265 ] ;
6366
64- const { searchEntries } = await this . ldapClient . search ( process . env . LDAP_SEARCH_DN , {
65- filter : process . env . LDAP_USERS_SEARCH_FILTER . replaceAll ( '{{email}}' , email ) ,
67+ const { searchEntries } = await this . ldapClient . search ( this . ldapConfig . searchDN , {
68+ filter : this . ldapConfig . usersSearchFilter . replaceAll ( '{{email}}' , email ) ,
6669 sizeLimit : 1 ,
6770 attributes : attributes ,
6871 } ) ;
@@ -84,9 +87,9 @@ export class LdapUsersService implements UsersService {
8487
8588 private async createUserFromLdapEntry ( ldapEntry : LdapEntry ) : Promise < User > {
8689 const userForVRTDb = {
87- email : ldapEntry [ process . env . LDAP_ATTRIBUTE_MAIL ] . toString ( ) . trim ( ) . toLowerCase ( ) ,
88- firstName : ldapEntry [ process . env . LDAP_ATTRIBUTE_FIRST_NAME ] . toString ( ) ,
89- lastName : ldapEntry [ process . env . LDAP_ATTRIBUTE_LAST_NAME ] . toString ( ) ,
90+ email : ldapEntry [ this . ldapConfig . attributeMail ] . toString ( ) . trim ( ) . toLowerCase ( ) ,
91+ firstName : ldapEntry [ this . ldapConfig . attributeFirstName ] . toString ( ) ,
92+ lastName : ldapEntry [ this . ldapConfig . attributeLastName ] . toString ( ) ,
9093 apiKey : this . authService . generateApiKey ( ) ,
9194 password : await this . authService . encryptPassword ( Math . random ( ) . toString ( 36 ) . slice ( - 8 ) ) ,
9295 role : Role . editor ,
@@ -97,35 +100,11 @@ export class LdapUsersService implements UsersService {
97100 } ) ;
98101 }
99102
103+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
100104 async create ( createUserDto : CreateUserDto ) : Promise < UserLoginResponseDto > {
101105 throw new HttpException ( 'User creation is disabled. Use your LDAP-Credentials to login.' , HttpStatus . BAD_REQUEST ) ;
102106 }
103107
104- async findOne ( id : string ) : Promise < User > {
105- return this . prismaService . user . findUnique ( { where : { id } } ) ;
106- }
107-
108- async delete ( id : string ) : Promise < User > {
109- this . logger . debug ( `Removing User: ${ id } ` ) ;
110- return this . prismaService . user . delete ( { where : { id } } ) ;
111- }
112-
113- async get ( id : string ) : Promise < UserDto > {
114- const user = await this . findOne ( id ) ;
115- return new UserDto ( user ) ;
116- }
117-
118- async assignRole ( data : AssignRoleDto ) : Promise < UserDto > {
119- const { id, role } = data ;
120- this . logger . debug ( `Assigning role ${ role } to User: ${ id } ` ) ;
121-
122- const user = await this . prismaService . user . update ( {
123- where : { id } ,
124- data : { role } ,
125- } ) ;
126- return new UserDto ( user ) ;
127- }
128-
129108 async update ( id : string , userDto : UpdateUserDto ) : Promise < UserLoginResponseDto > {
130109 const userFromLdap = await this . findUserInLdap ( userDto . email ) ;
131110 const user = await this . prismaService . user . update ( {
@@ -140,17 +119,7 @@ export class LdapUsersService implements UsersService {
140119 return new UserLoginResponseDto ( user , token ) ;
141120 }
142121
143- async generateNewApiKey ( user : User ) : Promise < string > {
144- const newApiKey = this . authService . generateApiKey ( ) ;
145- await this . prismaService . user . update ( {
146- where : { id : user . id } ,
147- data : {
148- apiKey : newApiKey ,
149- } ,
150- } ) ;
151- return newApiKey ;
152- }
153-
122+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
154123 async changePassword ( user : User , newPassword : string ) : Promise < boolean > {
155124 this . logger . warn ( `${ user . email } tied to change password - this is not supported for LDAP users` ) ;
156125 return true ;
@@ -171,7 +140,7 @@ export class LdapUsersService implements UsersService {
171140 await this . ldapClient . unbind ( ) ;
172141 }
173142
174- const userEmailFromLdap = userFromLdap [ process . env . LDAP_ATTRIBUTE_MAIL ] . toString ( ) . trim ( ) . toLowerCase ( ) ;
143+ const userEmailFromLdap = userFromLdap [ this . ldapConfig . attributeMail ] . toString ( ) . trim ( ) . toLowerCase ( ) ;
175144
176145 let user = await this . prismaService . user . findUnique ( {
177146 where : { email : userEmailFromLdap } ,
0 commit comments