diff --git a/src/common/env.ts b/src/common/env.ts index 9450088..863a7b7 100644 --- a/src/common/env.ts +++ b/src/common/env.ts @@ -1,2 +1,7 @@ export const MAP_TIMEOUT_IN_MINUTES = process.env.MAPPING_TIMEOUT || '720' // 12 horas + export const JWT_SECRET = process.env.JWT_SECRET || 'somERand0mStr1ng' + +export const JWT_TTL_IN_MINUTES = Number( + process.env.JWT_TTL_IN_MINUTES || 43000 +) // 30 dias diff --git a/src/server/auth/FakeAuth.ts b/src/server/auth/FakeAuth.ts index 6189a5a..4a76453 100644 --- a/src/server/auth/FakeAuth.ts +++ b/src/server/auth/FakeAuth.ts @@ -1,15 +1,16 @@ import { Auth } from '../schemas/Auth' -import { LoginResult } from '../schemas/LoginResult' +import { AuthResult } from '../schemas/AuthResult' export class FakeAuth implements Auth { constructor() {} - async login(username: string, password: string): Promise { + async login(username: string, password: string): Promise { if (username == 'test' && password == 'test') return { displayName: 'Test User', username: 'test', - domain: 'test_domain' + domain: 'test_domain', + pwdLastSet: '2021-01-01' } throw new Error('Fake login failed') } diff --git a/src/server/auth/LdapAuth.ts b/src/server/auth/LdapAuth.ts index dcdcdf2..7700736 100644 --- a/src/server/auth/LdapAuth.ts +++ b/src/server/auth/LdapAuth.ts @@ -1,6 +1,6 @@ import { Client } from 'ldapts' import { Auth } from '../schemas/Auth' -import { LoginResult } from '../schemas/LoginResult' +import { AuthResult } from '../schemas/AuthResult' export class LdapAuth implements Auth { constructor( @@ -9,7 +9,7 @@ export class LdapAuth implements Auth { private searchDN: string ) {} - async login(username: string, password: string): Promise { + async login(username: string, password: string): Promise { try { await this.client.bind(`${this.domain}\\${username}`, password) @@ -22,7 +22,8 @@ export class LdapAuth implements Auth { return { username, displayName: search.searchEntries[0].displayName as string, - domain: this.domain + domain: this.domain, + pwdLastSet: search.searchEntries[0].pwdLastSet as string } } catch (error: any) { console.log('Error:', error) diff --git a/src/server/lib/jwt.ts b/src/server/lib/jwt.ts new file mode 100644 index 0000000..f20361c --- /dev/null +++ b/src/server/lib/jwt.ts @@ -0,0 +1,3 @@ +import { JwtService } from '../services/JwtService' + +export const jwtService = new JwtService() diff --git a/src/server/lib/login.ts b/src/server/lib/login.ts index 2d372bc..79ca789 100644 --- a/src/server/lib/login.ts +++ b/src/server/lib/login.ts @@ -3,8 +3,14 @@ import { Client } from 'ldapts' import { LdapAuth } from '../auth/LdapAuth' import { PaFirewallService } from '../services/PaFirewallService' import { db } from '../prisma' +import { LoginResult } from '../schemas/LoginResult' +import { jwtService } from './jwt' -export async function login(username: string, password: string, ip: string) { +export async function login( + username: string, + password: string, + ip: string +): Promise { const ldapClient = new Client({ url: 'ldap://10.7.0.18' }) @@ -20,7 +26,17 @@ export async function login(username: string, password: string, ip: string) { await pa.login(username, ip, user.domain) - return user + const jwt = await jwtService.generateToken({ + displayName: user.displayName, + username: user.username, + domain: user.domain, + pwdLastSet: user.pwdLastSet + }) + + return { + ...user, + jwt + } } catch (error: any) { console.log(error.message) throw new Error(`Login procedure failed: ${error.message}`) diff --git a/src/server/schemas/AuthResult.ts b/src/server/schemas/AuthResult.ts new file mode 100644 index 0000000..9204af9 --- /dev/null +++ b/src/server/schemas/AuthResult.ts @@ -0,0 +1,6 @@ +export type AuthResult = { + username: string + displayName: string + domain: string + pwdLastSet: string +} diff --git a/src/server/schemas/JwtPayload.ts b/src/server/schemas/JwtPayload.ts index 1531b93..bb5b20e 100644 --- a/src/server/schemas/JwtPayload.ts +++ b/src/server/schemas/JwtPayload.ts @@ -3,6 +3,6 @@ export type JwtPayload = { displayName: string domain: string pwdLastSet: string - iat: Date // issued at - exp: Date // expires at + iat?: Date // issued at + exp?: Date // expires at } diff --git a/src/server/schemas/LoginResult.ts b/src/server/schemas/LoginResult.ts index ff67c58..454eb3d 100644 --- a/src/server/schemas/LoginResult.ts +++ b/src/server/schemas/LoginResult.ts @@ -1,6 +1,5 @@ -export type LoginResult = { - username: string - displayName: string - domain: string +import { AuthResult } from './AuthResult' + +export type LoginResult = AuthResult & { jwt?: string } diff --git a/src/server/services/JwtService.ts b/src/server/services/JwtService.ts index 8c58fcd..4e51e13 100644 --- a/src/server/services/JwtService.ts +++ b/src/server/services/JwtService.ts @@ -1,10 +1,11 @@ import { sign, verify } from 'jsonwebtoken' import { JwtPayload } from '../schemas/JwtPayload' +import { JWT_SECRET, JWT_TTL_IN_MINUTES } from '../../common/env' export class JwtService { constructor( - private readonly jwtSecret: string, - private readonly ttlInMinutes: number + private readonly jwtSecret: string = JWT_SECRET, + private readonly ttlInMinutes: number = JWT_TTL_IN_MINUTES ) {} generateToken(payload: JwtPayload): string { @@ -16,8 +17,8 @@ export class JwtService { } verifyToken(token: string): JwtPayload { - const payload = verify(token, this.jwtSecret) as JwtPayload + const decoded = verify(token, this.jwtSecret) as unknown - return payload + return decoded as JwtPayload } }