import { inject } from '@loopback/context'; import { HttpErrors, Request } from '@loopback/rest'; import { AuthenticationStrategy } from '@loopback/authentication'; import { UserServiceBindings, UserService } from '../services'; import { User, UserProfile, UserCredentials } from '../data'; export class AuthStrategyBasic implements AuthenticationStrategy { name: string = 'basic'; constructor( @inject(UserServiceBindings.SERVICE) private _userService: UserService, ){} async authenticate (request: Request): Promise { const credentials: UserCredentials = this.extractCredentials(request); const user: User = await this._userService.verifyCredentials(credentials); const userProfile: UserProfile = this._userService.convertToUserProfile(user); return userProfile; } extractCredentials (request: Request) { let credentials: UserCredentials = { 'login':'', 'password':'' }, parts = []; if (request.headers.authorization) { const authHeader = request.headers.authorization; if (!authHeader.startsWith("Basic")) throw new HttpErrors.Unauthorized(`Error: no valid authorization header`); parts = authHeader.split(' '); if (parts.length < 2) throw new HttpErrors.Unauthorized(`Error: no credentials value`); const credentialsStr = Buffer.from(parts[1], 'base64').toString('ascii'); if (!credentialsStr) throw new HttpErrors.Unauthorized(`Error: no valid credentials format`); parts = credentialsStr.split(':'); if (parts.length < 2) throw new HttpErrors.Unauthorized(`Error: invalid credentials value`); credentials.login = parts[0]; credentials.password = parts[1]; } else { throw new HttpErrors.Unauthorized(`Error: no authorization header`); } return credentials; } }