Skip to content

Commit

Permalink
feat: implemented awthentication-jwt refreshtoken services
Browse files Browse the repository at this point in the history
  • Loading branch information
madaky committed Jul 27, 2020
1 parent f8ed867 commit d05307b
Show file tree
Hide file tree
Showing 14 changed files with 181 additions and 247 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {UserServiceBindings} from '../..';
import {OPERATION_SECURITY_SPEC, SECURITY_SCHEME_SPEC} from '../../';
import {UserRepository} from '../../repositories';
import {TestApplication} from '../fixtures/application';
import {RefreshTokenBindings} from '../../keys';

describe('jwt authentication', () => {
let app: TestApplication;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import path from 'path';
import {
JWTAuthenticationComponent,
UserServiceBindings,
RefreshTokenBindings,
RefreshTokenServiceBindings,
} from '../../';
import {DbDataSource} from './datasources/db.datasource';
import {MySequence} from './sequence';
Expand All @@ -39,7 +39,7 @@ export class TestApplication extends BootMixin(
// Bind datasource
this.dataSource(DbDataSource, UserServiceBindings.DATASOURCE_NAME);
//Bind datasource for refreshtoken table
this.dataSource(DbDataSource, RefreshTokenBindings.DATASOURCE_NAME);
this.dataSource(DbDataSource, RefreshTokenServiceBindings.DATASOURCE_NAME);

this.component(RestExplorerComponent);
this.projectRoot = __dirname;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
TokenService,
UserService,
} from '@loopback/authentication';
import {inject, intercept} from '@loopback/core';
import {inject} from '@loopback/core';
import {get, post, requestBody} from '@loopback/rest';
import {SecurityBindings, securityId, UserProfile} from '@loopback/security';
import {
Expand All @@ -18,11 +18,13 @@ import {
TokenObject,
RefreshGrantRequestBody,
RefreshGrant,
RefreshTokenServiceBindings,
} from '../../../';
import {model, property} from '@loopback/repository';
import {genSalt, hash} from 'bcryptjs';
import {UserRepository} from '../../../repositories';
import {Credentials} from '../../../services/user.service';
import {RefreshTokenService} from '../../../keys';

const CredentialsSchema = {
type: 'object',
Expand Down Expand Up @@ -66,6 +68,8 @@ export class UserController {
private user: UserProfile,
@inject(UserServiceBindings.USER_REPOSITORY)
public userRepository: UserRepository,
@inject(RefreshTokenServiceBindings.REFRESH_TOKEN_SERVICE)
public refreshService: RefreshTokenService,
) {}

@post('/users/signup', {
Expand Down Expand Up @@ -172,7 +176,6 @@ export class UserController {
},
},
})
@intercept('refresh-token-generate')
async refreshLogin(
@requestBody(CredentialsRequestBody) credentials: Credentials,
): Promise<TokenObject> {
Expand All @@ -182,11 +185,12 @@ export class UserController {
const userProfile: UserProfile = this.userService.convertToUserProfile(
user,
);
// create a JSON Web Token based on the user profile
const token = {
accessToken: await this.jwtService.generateToken(userProfile),
};
return token;
const accessToken = await this.jwtService.generateToken(userProfile);
const tokens = await this.refreshService.generateToken(
userProfile,
accessToken,
);
return tokens;
}

@post('/refresh', {
Expand All @@ -198,8 +202,8 @@ export class UserController {
schema: {
type: 'object',
properties: {
refreshToken: {
type: 'string',
accessToken: {
type: 'object',
},
},
},
Expand All @@ -208,11 +212,9 @@ export class UserController {
},
},
})
@intercept('refresh-token-grant')
async refresh(
@requestBody(RefreshGrantRequestBody) refreshGrant: RefreshGrant,
): Promise<{token: string}> {
const token = '';
return {token};
): Promise<TokenObject> {
return this.refreshService.refreshToken(refreshGrant.refreshToken);
}
}
15 changes: 4 additions & 11 deletions extensions/authentication-jwt/src/__tests__/unit/jwt.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// License text available at https://opensource.org/licenses/MIT

import {HttpErrors} from '@loopback/rest';
import {securityId, UserProfile} from '@loopback/security';
import {securityId} from '@loopback/security';
import {expect} from '@loopback/testlab';
import {JWTService} from '../../';

Expand All @@ -19,17 +19,11 @@ describe('token service', () => {
id: '1',
name: 'test',
};
type Setter<T> = (value?: T) => void;

const TOKEN_SECRET_VALUE = 'myjwts3cr3t';
const TOKEN_EXPIRES_IN_VALUE = '60';
const setCurrentUser: Setter<UserProfile> = userProfile => {
return userProfile;
};
const jwtService = new JWTService(
TOKEN_SECRET_VALUE,
TOKEN_EXPIRES_IN_VALUE,
setCurrentUser,
);

const jwtService = new JWTService(TOKEN_SECRET_VALUE, TOKEN_EXPIRES_IN_VALUE);

it('token service generateToken() succeeds', async () => {
const token = await jwtService.generateToken(USER_PROFILE);
Expand All @@ -39,7 +33,6 @@ describe('token service', () => {
it('token service verifyToken() succeeds', async () => {
const token = await jwtService.generateToken(USER_PROFILE);
const userProfileFromToken = await jwtService.verifyToken(token);

expect(userProfileFromToken).to.deepEqual(DECODED_USER_PROFILE);
});

Expand Down
3 changes: 0 additions & 3 deletions extensions/authentication-jwt/src/interceptors/index.ts

This file was deleted.

This file was deleted.

This file was deleted.

35 changes: 14 additions & 21 deletions extensions/authentication-jwt/src/jwt-authentication-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,18 @@ import {
TokenServiceBindings,
TokenServiceConstants,
UserServiceBindings,
RefreshTokenInterceptorConstants,
RefreshTokenInterceptorBindings,
RefreshTokenBindings,
RefreshTokenConstants,
RefreshTokenServiceBindings,
} from './keys';
import {
UserCredentialsRepository,
UserRepository,
RefreshTokenRepository,
} from './repositories';
import {MyUserService} from './services';
import {MyUserService, RefreshtokenService} from './services';
import {JWTAuthenticationStrategy} from './services/jwt.auth.strategy';
import {JWTService} from './services/jwt.service';
import {SecuritySpecEnhancer} from './services/security.spec.enhancer';
import {
RefreshTokenGenerateInterceptor,
RefreshTokenGrantInterceptor,
} from './interceptors';

export class JWTAuthenticationComponent implements Component {
bindings: Binding[] = [
Expand All @@ -53,24 +48,22 @@ export class JWTAuthenticationComponent implements Component {
),
createBindingFromClass(SecuritySpecEnhancer),
///refresh bindings
Binding.bind(
RefreshTokenInterceptorConstants.REFRESH_INTERCEPTOR_NAME,
).toProvider(RefreshTokenGenerateInterceptor),
Binding.bind(
RefreshTokenInterceptorConstants.REFRESH_INTERCEPTOR_GRANT_TYPE,
).toProvider(RefreshTokenGrantInterceptor),
Binding.bind(RefreshTokenServiceBindings.REFRESH_TOKEN_SERVICE).toClass(
RefreshtokenService,
),

// Refresh token bindings
Binding.bind(RefreshTokenInterceptorBindings.REFRESH_SECRET).to(
RefreshTokenInterceptorConstants.REFRESH_SECRET_VALUE,
Binding.bind(RefreshTokenServiceBindings.REFRESH_SECRET).to(
RefreshTokenConstants.REFRESH_SECRET_VALUE,
),
Binding.bind(RefreshTokenInterceptorBindings.REFRESH_EXPIRES_IN).to(
RefreshTokenInterceptorConstants.REFRESH_EXPIRES_IN_VALUE,
Binding.bind(RefreshTokenServiceBindings.REFRESH_EXPIRES_IN).to(
RefreshTokenConstants.REFRESH_EXPIRES_IN_VALUE,
),
Binding.bind(RefreshTokenInterceptorBindings.REFRESH_ISSURE).to(
RefreshTokenInterceptorConstants.REFRESH_ISSURE_VALUE,
Binding.bind(RefreshTokenServiceBindings.REFRESH_ISSURE).to(
RefreshTokenConstants.REFRESH_ISSURE_VALUE,
),
//refresh token repository binding
Binding.bind(RefreshTokenBindings.REFRESH_REPOSITORY).toClass(
Binding.bind(RefreshTokenServiceBindings.REFRESH_REPOSITORY).toClass(
RefreshTokenRepository,
),
];
Expand Down
Loading

0 comments on commit d05307b

Please sign in to comment.