import { inject } from '@loopback/context'; import { CoreBindings, } from '@loopback/core'; import { repository } from '@loopback/repository'; import { HttpErrors, RestApplication } from '@loopback/rest'; import { UserService, PasswordService } from './types'; import { PermissionChecker } from '.'; import { UserServiceBindings, PasswordServiceBindings, PermissionServiceBindings } from './keys'; import { User, UserGroup, UserToGroup, UserCredentials, UserProfile, UserRepository, UserGroupRepository, UserToGroupRepository } from '../data'; export class AppUserService implements UserService { protected _userRepo: UserRepository; protected _userGroupRepo: UserGroupRepository; protected _userToGroupRepo: UserToGroupRepository; constructor ( @inject(PasswordServiceBindings.SERVICE) private _passService: PasswordService, @inject(PermissionServiceBindings.SERVICE) private _permService: PermissionChecker, @inject(CoreBindings.APPLICATION_INSTANCE) protected app: RestApplication, // @repository(UserServiceBindings.REPO_USER) private _userRepo: UserRepository, // error to build component // @inject(UserServiceBindings.REPO_USER) private _userRepo: UserRepository, // error to start app // @inject(UserServiceBindings.REPO_GROUP) private _userGroupRepo: UserGroupRepository, // -||- // @inject(UserServiceBindings.REPO_USR2GRP) private _userToGroupRepo: UserToGroupRepository, // -||- ) { this.app.get(UserServiceBindings.REPO_USER) .then((userRepo) => { this._userRepo = userRepo; }) .catch((e) => { console.log('ERROR: user repo'); }); this.app.get(UserServiceBindings.REPO_GROUP) .then((userGroupRepo) => { this._userGroupRepo = userGroupRepo; }) .catch((e) => { console.log('ERROR: user group repo'); }); this.app.get(UserServiceBindings.REPO_USR2GRP) .then((userToGroupRepo) => { this._userToGroupRepo = userToGroupRepo; }) .catch((e) => { console.log('ERROR: user to group repo'); }); } async verifyCredentials (credentials: UserCredentials): Promise { console.log(`Verify credentials: `,credentials); const user = await this._userRepo.findOne({ where: { email: credentials.login }, }); if (!user) throw new HttpErrors.NotFound(`Error: user not found by credentials`); const isMatched = await this._passService.verify(user.password, credentials.password); if (!isMatched) throw new HttpErrors.Unauthorized(`Error: invalid credentials`); user.groups = await this.getUserGroups(user); const allowed = await this._permService.isAllowed(user) if (!allowed) throw new HttpErrors.Forbidden(`Error: access not allowed`); return user; } convertToUserProfile (user: User): UserProfile { const userProfile: UserProfile = { "id": Number(user.id).toString(), "username": user.username, "email": user.email, }; return userProfile; } async getUserGroups (user: User): Promise { // get groups let groups: UserGroup[] = [], u2g: UserToGroup, u2gs: UserToGroup[] = await this._userRepo.getToGroups(user.id).find(); try { for (u2g of u2gs) { if (u2g.id) groups.push(await this._userToGroupRepo.getGroup(u2g.id)); } } catch (err) { } return groups; } }