switching user module to msgraph module
This commit is contained in:
4
libs/modules/src/auth/auth.controller.ts
Normal file
4
libs/modules/src/auth/auth.controller.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Controller } from '@nestjs/common';
|
||||
|
||||
@Controller('auth-controller')
|
||||
export class AuthControllerController {}
|
||||
@@ -1,10 +1,11 @@
|
||||
import { ExecutionContext, Injectable } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { AuthGuard as PassportAuthGuard } from '@nestjs/passport';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Injectable()
|
||||
export class AuthGuard extends PassportAuthGuard('oidc') {
|
||||
constructor() {
|
||||
export class AuthGuard extends PassportAuthGuard('jwt') {
|
||||
constructor(private readonly reflector: Reflector) {
|
||||
super();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
export interface AuthModuleOptions {
|
||||
authorizationUrl: string;
|
||||
issuer: string;
|
||||
callbackUrl: string;
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
scope: string;
|
||||
tokenUrl: string;
|
||||
userInfoUrl: string;
|
||||
audience: string;
|
||||
issuerUrl: string;
|
||||
jwksUri: string;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { PassportModule } from '@nestjs/passport';
|
||||
import { OidcStrategy } from './oidc.strategy';
|
||||
import { AuthStrategy } from './auth.strategy';
|
||||
import { ConfigurableModuleClass } from './auth.module-definition';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
PassportModule.register({
|
||||
defaultStrategy: 'oidc'
|
||||
defaultStrategy: 'jwt'
|
||||
})
|
||||
],
|
||||
providers: [
|
||||
OidcStrategy
|
||||
AuthStrategy
|
||||
]
|
||||
})
|
||||
export class AuthModule extends ConfigurableModuleClass {}
|
||||
|
||||
29
libs/modules/src/auth/auth.strategy.ts
Normal file
29
libs/modules/src/auth/auth.strategy.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { PassportStrategy } from '@nestjs/passport';
|
||||
import { ExtractJwt, Strategy } from 'passport-jwt';
|
||||
import * as jwksRsa from 'jwks-rsa';
|
||||
import { AuthModuleOptions } from './auth.interface';
|
||||
import { MODULE_OPTIONS_TOKEN } from './auth.module-definition';
|
||||
|
||||
@Injectable()
|
||||
export class AuthStrategy extends PassportStrategy(Strategy, 'jwt') {
|
||||
constructor(@Inject(MODULE_OPTIONS_TOKEN) authModuleOptions: AuthModuleOptions) {
|
||||
super({
|
||||
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
||||
audience: authModuleOptions.audience,
|
||||
issuer: authModuleOptions.issuerUrl,
|
||||
algorithms: ['RS256'],
|
||||
ignoreExpiration: false,
|
||||
secretOrKeyProvider: jwksRsa.passportJwtSecret({
|
||||
cache: true,
|
||||
rateLimit: true,
|
||||
jwksRequestsPerMinute: 5,
|
||||
jwksUri: authModuleOptions.jwksUri,
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
validate(payload: any) {
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import { PassportStrategy } from "@nestjs/passport";
|
||||
import { Strategy, Profile } from 'passport-openidconnect';
|
||||
import { MODULE_OPTIONS_TOKEN } from "./auth.module-definition";
|
||||
import { AuthModuleOptions } from "./auth.interface";
|
||||
import { Inject, Injectable } from "@nestjs/common";
|
||||
|
||||
@Injectable()
|
||||
export class OidcStrategy extends PassportStrategy(Strategy, 'oidc') {
|
||||
constructor(@Inject(MODULE_OPTIONS_TOKEN) authModuleOptions: AuthModuleOptions) {
|
||||
super({
|
||||
authorizationURL: authModuleOptions.authorizationUrl,
|
||||
callbackURL: authModuleOptions.callbackUrl,
|
||||
clientID: authModuleOptions.clientId,
|
||||
clientSecret: authModuleOptions.clientSecret,
|
||||
issuer: authModuleOptions.issuer,
|
||||
scope: authModuleOptions.scope,
|
||||
tokenURL: authModuleOptions.tokenUrl,
|
||||
userInfoURL: authModuleOptions.userInfoUrl
|
||||
})
|
||||
}
|
||||
|
||||
async validate(profile: Profile, done: Function): Promise<any> {
|
||||
const user = {
|
||||
id: profile.id,
|
||||
email: profile.emails,
|
||||
name: profile.displayName
|
||||
}
|
||||
|
||||
done(null, user)
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
import { SetMetadata } from "@nestjs/common";
|
||||
|
||||
export const IS_PUBLIC_KEY = 'isPublic'
|
||||
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
|
||||
@@ -1,14 +1,15 @@
|
||||
// Auth
|
||||
|
||||
export * from './auth/auth.module';
|
||||
export * from './auth/auth.gaurd';
|
||||
export * from './auth/public.decorator';
|
||||
export * from './auth/auth.guard';
|
||||
|
||||
// Custom Error
|
||||
|
||||
export * from './util/customError';
|
||||
|
||||
// User
|
||||
// MsGraph
|
||||
|
||||
export * from './msgraph/msgraph.module';
|
||||
export * from './msgraph/msgraph.service';
|
||||
|
||||
|
||||
export * from './user/user.module';
|
||||
export * from './user/user.service';
|
||||
|
||||
1
libs/modules/src/msgraph/msgraph.constants.ts
Normal file
1
libs/modules/src/msgraph/msgraph.constants.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const MSGRAPH_MODULE_OPTIONS = 'MSGRAPH_MODULE_OPTIONS'
|
||||
@@ -6,26 +6,26 @@ import {
|
||||
StreamableFile,
|
||||
UseGuards,
|
||||
} from '@nestjs/common';
|
||||
import { UserService } from './user.service';
|
||||
import { MsGraphService } from './msgraph.service';
|
||||
import { Client as MsGraphClient } from '@microsoft/microsoft-graph-client';
|
||||
import { AuthGuard } from '../auth/auth.gaurd';
|
||||
import { AuthGuard } from '../auth/auth.guard';
|
||||
|
||||
@Controller('user')
|
||||
export class UserController {
|
||||
@Controller('msgraph')
|
||||
export class MsGraphController {
|
||||
constructor(
|
||||
private readonly userService: UserService
|
||||
private readonly msGraphService: MsGraphService
|
||||
) {}
|
||||
|
||||
@Get('photo')
|
||||
@UseGuards(AuthGuard)
|
||||
async getProfilePhoto(@Headers() headers: any): Promise<StreamableFile> {
|
||||
try {
|
||||
const graphToken: string = await this.userService.getMsGraphAuth(
|
||||
const graphToken: string = await this.msGraphService.getMsGraphAuth(
|
||||
headers.authorization.replace('Bearer ', ''),
|
||||
['user.read']
|
||||
);
|
||||
const client: MsGraphClient =
|
||||
await this.userService.getMsGraphClientDelegated(graphToken);
|
||||
await this.msGraphService.getMsGraphClientDelegated(graphToken);
|
||||
const blob: Blob = await client.api(`me/photos('48x48')/$value`).get();
|
||||
const arrayBuffer: ArrayBuffer = await blob.arrayBuffer();
|
||||
const buffer: Buffer = Buffer.from(arrayBuffer);
|
||||
@@ -43,12 +43,12 @@ export class UserController {
|
||||
@UseGuards(AuthGuard)
|
||||
async getUserProfile(@Headers() headers: any): Promise<any> {
|
||||
try {
|
||||
const graphToken: string = await this.userService.getMsGraphAuth(
|
||||
const graphToken: string = await this.msGraphService.getMsGraphAuth(
|
||||
headers.authorization.replace('Bearer ', ''),
|
||||
['user.read']
|
||||
);
|
||||
const client: MsGraphClient =
|
||||
await this.userService.getMsGraphClientDelegated(graphToken);
|
||||
await this.msGraphService.getMsGraphClientDelegated(graphToken);
|
||||
const userProfile = await client.api(`me`).get();
|
||||
|
||||
return userProfile;
|
||||
@@ -66,7 +66,7 @@ export class UserController {
|
||||
try {
|
||||
const accessToken: string = headers.authorization.replace('Bearer ', '');
|
||||
const personSearchResults: any[] =
|
||||
await this.userService.searchUsers(accessToken, search);
|
||||
await this.msGraphService.searchUsers(accessToken, search);
|
||||
|
||||
return personSearchResults;
|
||||
} catch (error) {
|
||||
@@ -1,4 +1,4 @@
|
||||
export interface UserModuleOptions {
|
||||
export interface MsGraphModuleOptions {
|
||||
tenantId: string;
|
||||
clientId: string;
|
||||
clientSecret: string;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ConfigurableModuleBuilder } from '@nestjs/common';
|
||||
import { UserModuleOptions } from './user.interface';
|
||||
import { MsGraphModuleOptions } from './msgraph.interface';
|
||||
|
||||
export const { ConfigurableModuleClass, ASYNC_OPTIONS_TYPE, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE } = new ConfigurableModuleBuilder<UserModuleOptions>().build()
|
||||
export const { ConfigurableModuleClass, ASYNC_OPTIONS_TYPE, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE } = new ConfigurableModuleBuilder<MsGraphModuleOptions>().build()
|
||||
11
libs/modules/src/msgraph/msgraph.module.ts
Normal file
11
libs/modules/src/msgraph/msgraph.module.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { MsGraphService } from './msgraph.service';
|
||||
import { ConfigurableModuleClass } from './msgraph.module-definition';
|
||||
import { MsGraphController } from './msgraph.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [MsGraphController],
|
||||
providers: [MsGraphService],
|
||||
exports: [MsGraphService]
|
||||
})
|
||||
export class MsGraphModule extends ConfigurableModuleClass {}
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Inject, Injectable, StreamableFile } from '@nestjs/common';
|
||||
import { UserModuleOptions } from './user.interface';
|
||||
import { MsGraphModuleOptions } from './msgraph.interface';
|
||||
import { Client } from '@microsoft/microsoft-graph-client';
|
||||
import { AuthenticationResult, ConfidentialClientApplication, OnBehalfOfRequest } from '@azure/msal-node';
|
||||
import { MODULE_OPTIONS_TOKEN } from './user.module-definition';
|
||||
import { MODULE_OPTIONS_TOKEN } from './msgraph.module-definition';
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
constructor(@Inject(MODULE_OPTIONS_TOKEN) private userModuleOptions: UserModuleOptions) {}
|
||||
export class MsGraphService {
|
||||
constructor(@Inject(MODULE_OPTIONS_TOKEN) private msGraphModuleOptions: MsGraphModuleOptions) {}
|
||||
|
||||
async getMsGraphAuth(accessToken: string, scopes: string[]): Promise<string> {
|
||||
try {
|
||||
@@ -16,9 +16,9 @@ export class UserService {
|
||||
}
|
||||
const cca = new ConfidentialClientApplication({
|
||||
auth: {
|
||||
clientId: this.userModuleOptions.clientId,
|
||||
clientSecret: this.userModuleOptions.clientSecret,
|
||||
authority: `https://login.microsoftonline.com/${this.userModuleOptions.tenantId}`
|
||||
clientId: this.msGraphModuleOptions.clientId,
|
||||
clientSecret: this.msGraphModuleOptions.clientSecret,
|
||||
authority: `https://login.microsoftonline.com/${this.msGraphModuleOptions.tenantId}`
|
||||
}
|
||||
});
|
||||
const authenticationResult: AuthenticationResult = await cca.acquireTokenOnBehalfOf(oboRequest);
|
||||
@@ -1 +0,0 @@
|
||||
export const USER_MODULE_OPTIONS = 'USER_MODULE_OPTIONS'
|
||||
@@ -1,11 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { UserService } from './user.service';
|
||||
import { ConfigurableModuleClass } from './user.module-definition';
|
||||
import { UserController } from './user.controller';
|
||||
|
||||
@Module({
|
||||
controllers: [UserController],
|
||||
providers: [UserService],
|
||||
exports: [UserService]
|
||||
})
|
||||
export class UserModule extends ConfigurableModuleClass {}
|
||||
@@ -5,5 +5,5 @@
|
||||
"outDir": "../../dist/libs/modules"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
|
||||
"exclude": ["node_modules", "src/**/*.spec.ts"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user