import ApplicationComponent from "wms-core/ApplicationComponent"; import {Express, Router} from "express"; import ldap, {InsufficientAccessRightsError, InvalidCredentialsError, Server} from "ldapjs"; import Logger from "wms-core/Logger"; import Username from "./models/Username"; import UserEmail from "wms-core/auth/models/UserEmail"; import {PasswordAuthProof} from "./models/UserPassword"; import Throttler from "wms-core/Throttler"; export default class LDAPServerComponent extends ApplicationComponent { private server?: Server; public async start(app: Express, router: Router): Promise { this.server = ldap.createServer({ log: console }); let authorize = (req: any, res: any, next: any) => { Logger.debug(req); if (!req.connection.ldap.bindDN.equals('cn=root')) return next(new InsufficientAccessRightsError()); return next(); }; this.server.bind('ou=users,dc=toot,dc=party', async (req: any, res: any, next: any) => { const rdns = req.dn.toString().split(', ').map((rdn: string) => rdn.split('=')); let username; let email; for (const rdn of rdns) { if (rdn[0] === 'cn') { username = rdn[1]; } else if (rdn[0] === 'email') { email = rdn[1]; } } Logger.debug('Matrix authentication attempt:', username, email); try { Throttler.throttle('ldap_auth', 3, 30 * 1000, username); } catch (e) { Logger.debug('Too many auth requests'); next(new InvalidCredentialsError()); return; } const user = await Username.getUserFromUsername(username); if (user) { const email = await UserEmail.getMainFromUser(user.id!); if (email) { const authProof = new PasswordAuthProof(email.email!); if (await authProof.authorize(req.credentials)) { Logger.debug('Success'); res.end(); return; } } } Logger.debug('Fail'); next(new InvalidCredentialsError()); }); this.server.unbind((req: any, res: any, next: any) => { Logger.debug('Unbind', req); next(); }); this.server.listen(8389, '127.0.0.1', () => { Logger.info(`LDAP server listening on ${this.server!.url}`); }); } public async stop(): Promise { } }