Skip to content

Commit 06ab5a9

Browse files
author
hirsch88
committed
Add auth checkers
1 parent 2f3e2cc commit 06ab5a9

File tree

7 files changed

+94
-77
lines changed

7 files changed

+94
-77
lines changed

src/api/models/User.ts

+4
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@ export class User extends BaseEntity {
2020
@Column()
2121
public email: string;
2222

23+
public toString(): string {
24+
return `${this.firstName} ${this.lastName} (${this.email})`;
25+
}
26+
2327
}

src/app.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ import { swaggerLoader } from './loaders/swaggerLoader';
2222
import { monitorLoader } from './loaders/monitorLoader';
2323
import { homeLoader } from './loaders/homeLoader';
2424
import { publicLoader } from './loaders/publicLoader';
25+
import { iocLoader } from './loaders/iocLoader';
2526

2627

2728
bootstrapMicroframework({
2829
loaders: [
2930
winstonLoader,
30-
expressLoader,
31+
iocLoader,
3132
typeormLoader,
33+
expressLoader,
3234
swaggerLoader,
3335
monitorLoader,
3436
homeLoader,

src/auth/authorizationChecker.ts

+26-23
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,36 @@
11
import { Action } from 'routing-controllers';
22
import { Container } from 'typedi';
3+
import { Connection } from 'typeorm';
34
import { AuthService } from './AuthService';
45
import { Log } from '../core/Log';
56

6-
const log = new Log(__filename);
7-
const authService = Container.get(AuthService);
87

8+
export function authorizationChecker(connection: Connection): (action: Action, roles: any[]) => Promise<boolean> | boolean {
9+
const log = new Log(__filename);
10+
const authService = Container.get(AuthService);
911

10-
export async function authorizationChecker(action: Action, roles: string[]): Promise<boolean> {
11-
// here you can use request/response objects from action
12-
// also if decorator defines roles it needs to access the action
13-
// you can use them to provide granular access check
14-
// checker must return either boolean (true or false)
15-
// either promise that resolves a boolean value
16-
// demo code:
17-
const token = authService.parseTokenFromRequest(action.request);
12+
return async function innerAuthorizationChecker(action: Action, roles: string[]): Promise<boolean> {
13+
// here you can use request/response objects from action
14+
// also if decorator defines roles it needs to access the action
15+
// you can use them to provide granular access check
16+
// checker must return either boolean (true or false)
17+
// either promise that resolves a boolean value
18+
// demo code:
19+
const token = authService.parseTokenFromRequest(action.request);
1820

19-
if (token === null) {
20-
log.warn('No token given');
21-
return false; // res.failed(403, 'You are not allowed to request this resource!');
22-
}
21+
if (token === null) {
22+
log.warn('No token given');
23+
return false; // res.failed(403, 'You are not allowed to request this resource!');
24+
}
2325

24-
// Request user info at auth0 with the provided token
25-
try {
26-
action.request.tokeninfo = await authService.getTokenInfo(token);
27-
log.info('Successfully checked token');
28-
return true;
29-
} catch (e) {
30-
log.warn(e);
31-
return false;
32-
}
26+
// Request user info at auth0 with the provided token
27+
try {
28+
action.request.tokeninfo = await authService.getTokenInfo(token);
29+
log.info('Successfully checked token');
30+
return true;
31+
} catch (e) {
32+
log.warn(e);
33+
return false;
34+
}
35+
};
3336
}

src/auth/currentUserChecker.ts

+21-22
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,30 @@ import { Action } from 'routing-controllers';
22
import { User } from '../api/models/User';
33
import { Log } from '../core/Log';
44
import { ITokenInfo } from './ITokenInfo';
5-
// import { UserRepository } from '../api/repositories/UserRepository';
6-
// import { getConnection } from 'typeorm';
5+
import { Connection } from 'typeorm';
76

8-
const log = new Log(__filename);
97

8+
export function currentUserChecker(connection: Connection): (action: Action) => Promise<User | undefined> {
9+
const log = new Log(__filename);
1010

11-
export async function currentUserChecker(action: Action): Promise<User | undefined> {
12-
// here you can use request/response objects from action
13-
// you need to provide a user object that will be injected in controller actions
14-
// demo code:
15-
const tokeninfo: ITokenInfo = action.request.tokeninfo;
16-
log.info('todo user checker', tokeninfo);
11+
return async function innerCurrentUserChecker(action: Action): Promise<User | undefined> {
12+
// here you can use request/response objects from action
13+
// you need to provide a user object that will be injected in controller actions
14+
// demo code:
15+
const tokeninfo: ITokenInfo = action.request.tokeninfo;
16+
const em = connection.createEntityManager();
17+
const user = await em.findOne<User>(User, {
18+
where: {
19+
email: tokeninfo.user_id
20+
}
21+
});
22+
if (user) {
23+
log.info('Current user is ', user.toString());
24+
} else {
25+
log.info('Current user is undefined');
26+
}
1727

18-
// const connection = getConnection();
19-
20-
// const userRepository = connection.getRepository<User>(UserRepository);
21-
// console.log(connection);
22-
// const user = await userRepository.
23-
// findOne({
24-
// where: {
25-
// email: tokeninfo.user_id
26-
// }
27-
// });
28-
// console.log(user);
29-
30-
return Promise.resolve(new User());
28+
return Promise.resolve(user);
29+
};
3130
}
3231

src/loaders/expressLoader.ts

+24-31
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,41 @@
11
import * as path from 'path';
2-
import { Container } from 'typedi';
3-
import { useContainer as ormUseContainer } from 'typeorm';
4-
import { useContainer as routingUseContainer, createExpressServer } from 'routing-controllers';
2+
import { createExpressServer } from 'routing-controllers';
53
import { MicroframeworkSettings, MicroframeworkLoader } from 'microframework';
64
import { env } from '../core/env';
75
import { authorizationChecker } from '../auth/authorizationChecker';
86
import { currentUserChecker } from '../auth/currentUserChecker';
97

108

119
export const expressLoader: MicroframeworkLoader = (settings: MicroframeworkSettings | undefined) => {
10+
if (settings) {
11+
const connection = settings.getData('connection');
1212

13-
/**
14-
* Setup routing-controllers to use typedi container.
15-
*/
16-
routingUseContainer(Container);
17-
ormUseContainer(Container);
18-
19-
/**
20-
* We create a new express server instance.
21-
* We could have also use useExpressServer here to attach controllers to an existing express instance.
22-
*/
23-
const expressApp = createExpressServer({
24-
cors: true,
25-
routePrefix: env.app.routePrefix,
2613
/**
27-
* We can add options about how routing-controllers should configure itself.
28-
* Here we specify what controllers should be registered in our express server.
14+
* We create a new express server instance.
15+
* We could have also use useExpressServer here to attach controllers to an existing express instance.
2916
*/
30-
controllers: [path.join(__dirname, '..', 'api/controllers/*{.js,.ts}')],
31-
middlewares: [path.join(__dirname, '..', 'api/middlewares/*{.js,.ts}')],
32-
interceptors: [path.join(__dirname, '..', 'api/interceptors/*{.js,.ts}')],
17+
const expressApp = createExpressServer({
18+
cors: true,
19+
routePrefix: env.app.routePrefix,
20+
/**
21+
* TODO: We can add options about how routing-controllers should configure itself.
22+
* Here we specify what controllers should be registered in our express server.
23+
*/
24+
controllers: [path.join(__dirname, '..', 'api/controllers/*{.js,.ts}')],
25+
middlewares: [path.join(__dirname, '..', 'api/middlewares/*{.js,.ts}')],
26+
interceptors: [path.join(__dirname, '..', 'api/interceptors/*{.js,.ts}')],
3327

34-
/**
35-
* Authorization features
36-
*/
37-
authorizationChecker,
38-
currentUserChecker
39-
});
28+
/**
29+
* Authorization features
30+
*/
31+
authorizationChecker: authorizationChecker(connection),
32+
currentUserChecker: currentUserChecker(connection)
33+
});
4034

41-
// Run application to listen on given port
42-
expressApp.listen(env.app.port);
35+
// Run application to listen on given port
36+
expressApp.listen(env.app.port);
4337

44-
// Here we can set the data for other loaders
45-
if (settings) {
38+
// Here we can set the data for other loaders
4639
settings.setData('express_app', expressApp);
4740
}
4841
};

src/loaders/iocLoader.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Container } from 'typedi';
2+
import { useContainer as ormUseContainer } from 'typeorm';
3+
import { useContainer as routingUseContainer } from 'routing-controllers';
4+
import { MicroframeworkSettings, MicroframeworkLoader } from 'microframework';
5+
6+
7+
export const iocLoader: MicroframeworkLoader = (settings: MicroframeworkSettings | undefined) => {
8+
9+
/**
10+
* Setup routing-controllers to use typedi container.
11+
*/
12+
routingUseContainer(Container);
13+
ormUseContainer(Container);
14+
15+
};

src/loaders/typeormLoader.ts

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const typeormLoader: MicroframeworkLoader = async (settings: Microframewo
2121
});
2222

2323
if (settings) {
24+
settings.setData('connection', connection);
2425
settings.onShutdown(() => connection.close());
2526
}
2627
};

0 commit comments

Comments
 (0)