Skip to content

Commit

Permalink
fix: run tests
Browse files Browse the repository at this point in the history
  • Loading branch information
deepakrkris committed Mar 27, 2020
1 parent aec7aaa commit e890ee1
Show file tree
Hide file tree
Showing 9 changed files with 403 additions and 314 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import {TokenService, UserService} from '@loopback/authentication';
import {inject} from '@loopback/context';
import {post, requestBody} from '@loopback/rest';
import {post, requestBody, Response} from '@loopback/rest';
import {
Credentials,
TokenServiceBindings,
Expand Down
5 changes: 0 additions & 5 deletions examples/passport-oauth2-login/.dockerignore

This file was deleted.

4 changes: 0 additions & 4 deletions examples/passport-oauth2-login/.mocharc.json

This file was deleted.

547 changes: 324 additions & 223 deletions examples/passport-oauth2-login/package-lock.json

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions examples/passport-oauth2-login/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"!*/__tests__"
],
"dependencies": {
"@loopback/authentication": "^4.1.1",
"@loopback/authentication-passport": "^2.0.0",
"@loopback/boot": "^1.7.4",
"@loopback/context": "^2.1.1",
Expand All @@ -63,16 +64,17 @@
},
"devDependencies": {
"@loopback/build": "^3.1.1",
"source-map-support": "^0.5.16",
"@loopback/eslint-config": "^5.0.3",
"@loopback/security": "^0.2.2",
"@loopback/testlab": "^1.10.3",
"@types/node": "^10.17.14",
"@typescript-eslint/parser": "^2.19.0",
"@typescript-eslint/eslint-plugin": "^2.19.0",
"@loopback/eslint-config": "^5.0.3",
"@typescript-eslint/parser": "^2.19.0",
"eslint": "^6.8.0",
"eslint-config-prettier": "^6.10.0",
"eslint-plugin-eslint-plugin": "^2.2.1",
"eslint-plugin-mocha": "^6.2.2",
"source-map-support": "^0.5.16",
"typescript": "~3.7.5"
}
}
6 changes: 3 additions & 3 deletions examples/passport-oauth2-login/src/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
} from '@loopback/authentication';
import {inject} from '@loopback/context';
import {addExtension, CoreTags, Provider} from '@loopback/core';
import {UserController} from './controllers';
import {Oauth2Controller} from './controllers';

const facebookStrategy = new Strategy({
"clientID": "319451939015320",
Expand All @@ -50,7 +50,7 @@ export const myUserProfileFactory: UserProfileFactory<Profile> = function(

return userProfile;
};
ß

const FACEBOOK_STRATEGY_BINDING_KEY =
'authentication.strategies.facebookAuthStrategy';

Expand Down Expand Up @@ -90,7 +90,7 @@ export class Oauth2LoginApplication extends BootMixin(
});
this.component(RestExplorerComponent);

this.controller(UserController);
this.controller(Oauth2Controller);
this.component(AuthenticationComponent);

this.projectRoot = __dirname;
Expand Down
117 changes: 56 additions & 61 deletions examples/passport-oauth2-login/src/controllers/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,72 +3,67 @@
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

// Uncomment these imports to begin using these cool features!
import {get, RestBindings, Response} from '@loopback/rest';
import {authenticate} from '@loopback/authentication';
import {inject} from '@loopback/core';
import {SecurityBindings, securityId, UserProfile} from '@loopback/security';

import {User, UserCredentials, AccessToken} from '../models';
import {get, requestBody} from '@loopback/rest';
import {
authenticate,
AuthenticateFn,
AuthenticationBindings,
AuthenticationComponent,
AuthenticationStrategy,
AUTHENTICATION_STRATEGY_NOT_FOUND,
UserProfileFactory,
USER_PROFILE_NOT_FOUND,
} from '@loopback/authentication';
/**
* Login controller for third party oauth provider
*
* This creates an authentication endpoint for the third party oauth provider
*
* Two methods are expected
*
* 1. loginToThirdParty
* i. an endpoint for api clients to login via a third party app
* ii. the passport strategy identifies this call as a redirection to third party
* iii. this endpoint redirects to the third party authorization url
*
* 2. thirdPartyCallBack
* i. this is the callback for the thirdparty app
* ii. on successful user login the third party calls this endpoint with an access code
* iii. the passport oauth2 strategy exchanges the code for an access token
* iv. the passport oauth2 strategy then calls the provided `verify()` function with the access token
*/


const CredentialsSchema = {
type: 'object',
required: ['email', 'password'],
properties: {
email: {
type: 'string',
format: 'email',
},
password: {
type: 'string',
minLength: 8,
},
},
};

export const CredentialsRequestBody = {
description: 'The input of login function',
required: true,
content: {
'application/json': {schema: CredentialsSchema},
},
};

export class UserController {
export class Oauth2Controller {
constructor() {}

@authenticate('facebook')
@get('/auth/facebook', {
responses: {
'200': {
description: 'Token',
content: {
'application/json': {
schema: {
type: 'object',
properties: {
token: {
type: 'string',
},
},
},
},
},
},
},
})
async login(
@requestBody(CredentialsRequestBody) credentials: UserCredentials,
): Promise<{token: string}> {
// this configures the oauth2 strategy
@authenticate('oauth2')
// we have modeled this as a GET endpoint
@get('/auth/thirdparty')
// loginToThirdParty() is the handler for '/auth/thirdparty'
// this method is injected with redirect url and status
// the value for 'authentication.redirect.url' is set by the authentication action provider
loginToThirdParty(
@inject('authentication.redirect.url')
redirectUrl: string,
@inject('authentication.redirect.status')
status: number,
@inject(RestBindings.Http.RESPONSE)
response: Response,
) {
// controller handles redirect
// and returns response object to indicate response is already handled
response.statusCode = status || 302;
response.setHeader('Location', redirectUrl);
response.end();
return response;
}

return {token: ""};
// we configure the callback url also with the same oauth2 strategy
@authenticate('oauth2')
// this SHOULD be a GET call so that the third party can ask the browser to redirect
@get('/auth/thirdparty/callback')
// thirdPartyCallBack() is the handler for '/auth/thirdparty/callback'
// the oauth2 strategy identifies this as a callback with the request.query.code sent by the third party app
// the oauth2 strategy exchanges the access code for a access token and then calls the provided verify() function
// the verify function creates a user profile after verifying the access token
thirdPartyCallBack(@inject(SecurityBindings.USER) user: UserProfile) {
// eslint-disable-next-line @typescript-eslint/camelcase
return {access_token: user.token};
}
}
4 changes: 2 additions & 2 deletions examples/passport-oauth2-login/src/migrate.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {PassportFacebookApplication} from './application';
import {Oauth2LoginApplication} from './application';

export async function migrate(args: string[]) {
const existingSchema = args.includes('--rebuild') ? 'drop' : 'alter';
console.log('Migrating schemas (%s existing schema)', existingSchema);

const app = new PassportFacebookApplication();
const app = new Oauth2LoginApplication();
await app.boot();
await app.migrateSchema({existingSchema});

Expand Down
24 changes: 12 additions & 12 deletions examples/passport-oauth2-login/src/sequence.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,26 @@
import {
AuthenticateFn,
AuthenticationBindings,
} from '@loopback/authentication';
import {inject} from '@loopback/context';
import {
FindRoute,
InvokeMethod,
ParseParams,
Reject,
RequestContext,
RestApplication,
RestBindings,
RestServer,
Send,
SequenceHandler,
} from '@loopback/rest';
import {
authenticate,
AuthenticateFn,
AuthenticationBindings,
AuthenticationComponent,
AuthenticationStrategy,
AUTHENTICATION_STRATEGY_NOT_FOUND,
UserProfileFactory,
USER_PROFILE_NOT_FOUND,
} from '@loopback/authentication';

const SequenceActions = RestBindings.SequenceActions;

let app: RestApplication;
let server: RestServer;

export class MySequence implements SequenceHandler {
constructor(
@inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
Expand All @@ -46,8 +45,9 @@ export class MySequence implements SequenceHandler {
const args = await this.parseParams(request, route);
const result = await this.invoke(route, args);
this.send(response, result);
} catch (err) {
this.reject(context, err);
} catch (error) {
this.reject(context, error);
return;
}
}
}

0 comments on commit e890ee1

Please sign in to comment.