Skip to content

Commit

Permalink
fixup! more code
Browse files Browse the repository at this point in the history
  • Loading branch information
nabdelgadir committed Dec 20, 2018
1 parent df37b29 commit aded6b6
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 38 deletions.
1 change: 0 additions & 1 deletion src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
AuthenticationBindings,
AuthenticationComponent,
} from '@loopback/authentication';
import {JWTProvider} from './providers';
import {StrategyResolverProvider} from './providers/strategy.resolver.provider';

/**
Expand Down
30 changes: 30 additions & 0 deletions src/authentication-strategies/JWT.strategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const jwt = require('jsonwebtoken');
import {promisify} from 'util';
const signAsync = promisify(jwt.sign);
const verifyAsync = promisify(jwt.verify);
// Consider turn it to a binding
const SECRET = 'secretforjwt';

export class JWTStrategy {
// tslint:disable-next-line:no-any
async authenticate(request: Request): Promise<any> {
// A mock for sign in
const payload = {admin: true};
await signAsync(payload, SECRET, {expiresIn: 300});
// const token =
// request.body!.token ||
// request.query.token ||
// request.headers['x-access-token'];
const token = 'not the right token';

if (token) {
try {
return await verifyAsync(token, SECRET);
} catch (err) {
if (err) return Promise.reject('Authentication failed!');
}
}
// should we return some meaningful message?
return;
}
}
27 changes: 24 additions & 3 deletions src/controllers/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import {promisify} from 'util';
import * as isemail from 'isemail';
import {RecommenderService} from '../services/recommender.service';
import {inject} from '@loopback/core';
import {
authenticate,
} from '@loopback/authentication';
import {authenticate} from '@loopback/authentication';

const hashAsync = promisify(hash);

Expand Down Expand Up @@ -91,4 +89,27 @@ export class UserController {
): Promise<Product[]> {
return this.recommender.getProductRecommendations(userId);
}

@post('/users/login')
async login(@requestBody() user: User): Promise<User> {
// Validate Email
if (!isemail.validate(user.email)) {
throw new HttpErrors.UnprocessableEntity('invalid email');
}

// Validate Password Length
if (user.password.length < 8) {
throw new HttpErrors.UnprocessableEntity(
'password must be minimum 8 characters',
);
}

// Salt + Hash Password
user.password = await hashAsync(user.password, 10);

// Save & Return Result
const savedUser = await this.userRepository.create(user);
delete savedUser.password;
return savedUser;
}
}
32 changes: 1 addition & 31 deletions src/providers/strategy.resolver.provider.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import {Provider, ValueOrPromise} from '@loopback/core';
import {inject} from '@loopback/context';
import {
StrategyAdapter,
AuthenticationBindings,
AuthenticationMetadata,
} from '@loopback/authentication';
const jwt = require('jsonwebtoken');
import {promisify} from 'util';
const signAsync = promisify(jwt.sign);
const verifyAsync = promisify(jwt.verify);
// Consider turn it to a binding
const SECRET = 'secretforjwt';
import {JWTStrategy} from '../authentication-strategies/JWT.strategy';

export class StrategyResolverProvider
implements Provider<JWTStrategy | undefined> {
Expand All @@ -31,27 +25,3 @@ export class StrategyResolverProvider
}
}
}

export class JWTStrategy {
// tslint:disable-next-line:no-any
async authenticate(req: Request): Promise<any> {
// A mock for sign in
const payload = {admin: true};
await signAsync(payload, SECRET, {expiresIn: 5});
// const token =
// request.body.token ||
// request.query.token ||
// request.headers['x-access-token'];
const token = 'not the right token';

if (token) {
try {
await verifyAsync(token, SECRET);
} catch (err) {
if (err) return Promise.reject('Authentication failed!');
}
}
// should we return some meaningful message?
return;
}
}
5 changes: 2 additions & 3 deletions test/acceptance/user.controller.acceptance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import {UserRepository, OrderRepository} from '../../src/repositories';
import {MongoDataSource} from '../../src/datasources';
import {setupApplication} from './helper';
import {createRecommendationServer} from '../../recommender';
import {Server, ServerResponse} from 'http';
import {authenticate} from '@loopback/authentication';
import {Server} from 'http';
const recommendations = require('../../recommender/recommendations.json');

describe('UserController', () => {
Expand Down Expand Up @@ -121,7 +120,7 @@ describe('UserController', () => {
// since the REST API returns a string for the id property.
newUser.id = newUser.id.toString();
await client
.post('/Users/login')
.post('/users/login')
.send({username: 'the-username', password: 'the-password'})
.expect(200)
.end(onResponse);
Expand Down

0 comments on commit aded6b6

Please sign in to comment.