From 765c02c0a1d0739e305c7a0bf396cef91a69f9e5 Mon Sep 17 00:00:00 2001 From: Noah Spannbauer Date: Thu, 2 Oct 2025 11:59:30 -0500 Subject: [PATCH] switching user module to msgraph module --- libs/modules/src/auth/auth.controller.ts | 4 + .../src/auth/{auth.gaurd.ts => auth.guard.ts} | 5 +- libs/modules/src/auth/auth.interface.ts | 11 +- libs/modules/src/auth/auth.module.ts | 6 +- libs/modules/src/auth/auth.strategy.ts | 29 ++++ libs/modules/src/auth/oidc.strategy.ts | 31 ----- libs/modules/src/auth/public.decorator.ts | 4 - libs/modules/src/index.ts | 11 +- libs/modules/src/msgraph/msgraph.constants.ts | 1 + .../msgraph.controller.ts} | 20 +-- .../msgraph.interface.ts} | 2 +- .../msgraph.module-definition.ts} | 4 +- libs/modules/src/msgraph/msgraph.module.ts | 11 ++ .../msgraph.service.ts} | 14 +- libs/modules/src/user/user.constants.ts | 1 - libs/modules/src/user/user.module.ts | 11 -- libs/modules/tsconfig.lib.json | 2 +- package-lock.json | 127 +++++++++++++++--- package.json | 5 +- tsconfig.build.json | 2 +- 20 files changed, 194 insertions(+), 107 deletions(-) create mode 100644 libs/modules/src/auth/auth.controller.ts rename libs/modules/src/auth/{auth.gaurd.ts => auth.guard.ts} (68%) create mode 100644 libs/modules/src/auth/auth.strategy.ts delete mode 100644 libs/modules/src/auth/oidc.strategy.ts delete mode 100644 libs/modules/src/auth/public.decorator.ts create mode 100644 libs/modules/src/msgraph/msgraph.constants.ts rename libs/modules/src/{user/user.controller.ts => msgraph/msgraph.controller.ts} (73%) rename libs/modules/src/{user/user.interface.ts => msgraph/msgraph.interface.ts} (61%) rename libs/modules/src/{user/user.module-definition.ts => msgraph/msgraph.module-definition.ts} (67%) create mode 100644 libs/modules/src/msgraph/msgraph.module.ts rename libs/modules/src/{user/user.service.ts => msgraph/msgraph.service.ts} (87%) delete mode 100644 libs/modules/src/user/user.constants.ts delete mode 100644 libs/modules/src/user/user.module.ts diff --git a/libs/modules/src/auth/auth.controller.ts b/libs/modules/src/auth/auth.controller.ts new file mode 100644 index 0000000..71d700c --- /dev/null +++ b/libs/modules/src/auth/auth.controller.ts @@ -0,0 +1,4 @@ +import { Controller } from '@nestjs/common'; + +@Controller('auth-controller') +export class AuthControllerController {} diff --git a/libs/modules/src/auth/auth.gaurd.ts b/libs/modules/src/auth/auth.guard.ts similarity index 68% rename from libs/modules/src/auth/auth.gaurd.ts rename to libs/modules/src/auth/auth.guard.ts index 22229ff..52e8561 100644 --- a/libs/modules/src/auth/auth.gaurd.ts +++ b/libs/modules/src/auth/auth.guard.ts @@ -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(); } diff --git a/libs/modules/src/auth/auth.interface.ts b/libs/modules/src/auth/auth.interface.ts index 5ca9904..20b2e80 100644 --- a/libs/modules/src/auth/auth.interface.ts +++ b/libs/modules/src/auth/auth.interface.ts @@ -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; } diff --git a/libs/modules/src/auth/auth.module.ts b/libs/modules/src/auth/auth.module.ts index 81b4eac..c438014 100644 --- a/libs/modules/src/auth/auth.module.ts +++ b/libs/modules/src/auth/auth.module.ts @@ -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 {} diff --git a/libs/modules/src/auth/auth.strategy.ts b/libs/modules/src/auth/auth.strategy.ts new file mode 100644 index 0000000..04c15a6 --- /dev/null +++ b/libs/modules/src/auth/auth.strategy.ts @@ -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; + } +} \ No newline at end of file diff --git a/libs/modules/src/auth/oidc.strategy.ts b/libs/modules/src/auth/oidc.strategy.ts deleted file mode 100644 index 4c14f91..0000000 --- a/libs/modules/src/auth/oidc.strategy.ts +++ /dev/null @@ -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 { - const user = { - id: profile.id, - email: profile.emails, - name: profile.displayName - } - - done(null, user) - } -} \ No newline at end of file diff --git a/libs/modules/src/auth/public.decorator.ts b/libs/modules/src/auth/public.decorator.ts deleted file mode 100644 index 96e4125..0000000 --- a/libs/modules/src/auth/public.decorator.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { SetMetadata } from "@nestjs/common"; - -export const IS_PUBLIC_KEY = 'isPublic' -export const Public = () => SetMetadata(IS_PUBLIC_KEY, true); diff --git a/libs/modules/src/index.ts b/libs/modules/src/index.ts index 6e3b586..5a7bc05 100644 --- a/libs/modules/src/index.ts +++ b/libs/modules/src/index.ts @@ -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'; diff --git a/libs/modules/src/msgraph/msgraph.constants.ts b/libs/modules/src/msgraph/msgraph.constants.ts new file mode 100644 index 0000000..9aebff8 --- /dev/null +++ b/libs/modules/src/msgraph/msgraph.constants.ts @@ -0,0 +1 @@ +export const MSGRAPH_MODULE_OPTIONS = 'MSGRAPH_MODULE_OPTIONS' \ No newline at end of file diff --git a/libs/modules/src/user/user.controller.ts b/libs/modules/src/msgraph/msgraph.controller.ts similarity index 73% rename from libs/modules/src/user/user.controller.ts rename to libs/modules/src/msgraph/msgraph.controller.ts index e657a66..3fd7193 100644 --- a/libs/modules/src/user/user.controller.ts +++ b/libs/modules/src/msgraph/msgraph.controller.ts @@ -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 { 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 { 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) { diff --git a/libs/modules/src/user/user.interface.ts b/libs/modules/src/msgraph/msgraph.interface.ts similarity index 61% rename from libs/modules/src/user/user.interface.ts rename to libs/modules/src/msgraph/msgraph.interface.ts index c2eeb23..c9d3aca 100644 --- a/libs/modules/src/user/user.interface.ts +++ b/libs/modules/src/msgraph/msgraph.interface.ts @@ -1,4 +1,4 @@ -export interface UserModuleOptions { +export interface MsGraphModuleOptions { tenantId: string; clientId: string; clientSecret: string; diff --git a/libs/modules/src/user/user.module-definition.ts b/libs/modules/src/msgraph/msgraph.module-definition.ts similarity index 67% rename from libs/modules/src/user/user.module-definition.ts rename to libs/modules/src/msgraph/msgraph.module-definition.ts index ad7b387..8f90c5a 100644 --- a/libs/modules/src/user/user.module-definition.ts +++ b/libs/modules/src/msgraph/msgraph.module-definition.ts @@ -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().build() \ No newline at end of file +export const { ConfigurableModuleClass, ASYNC_OPTIONS_TYPE, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE } = new ConfigurableModuleBuilder().build() \ No newline at end of file diff --git a/libs/modules/src/msgraph/msgraph.module.ts b/libs/modules/src/msgraph/msgraph.module.ts new file mode 100644 index 0000000..6aed8cf --- /dev/null +++ b/libs/modules/src/msgraph/msgraph.module.ts @@ -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 {} \ No newline at end of file diff --git a/libs/modules/src/user/user.service.ts b/libs/modules/src/msgraph/msgraph.service.ts similarity index 87% rename from libs/modules/src/user/user.service.ts rename to libs/modules/src/msgraph/msgraph.service.ts index 6a44556..77348d5 100644 --- a/libs/modules/src/user/user.service.ts +++ b/libs/modules/src/msgraph/msgraph.service.ts @@ -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 { 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); diff --git a/libs/modules/src/user/user.constants.ts b/libs/modules/src/user/user.constants.ts deleted file mode 100644 index ec72cec..0000000 --- a/libs/modules/src/user/user.constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const USER_MODULE_OPTIONS = 'USER_MODULE_OPTIONS' \ No newline at end of file diff --git a/libs/modules/src/user/user.module.ts b/libs/modules/src/user/user.module.ts deleted file mode 100644 index 6de25eb..0000000 --- a/libs/modules/src/user/user.module.ts +++ /dev/null @@ -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 {} \ No newline at end of file diff --git a/libs/modules/tsconfig.lib.json b/libs/modules/tsconfig.lib.json index 282e925..727580e 100644 --- a/libs/modules/tsconfig.lib.json +++ b/libs/modules/tsconfig.lib.json @@ -5,5 +5,5 @@ "outDir": "../../dist/libs/modules" }, "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "test", "**/*spec.ts"] + "exclude": ["node_modules", "src/**/*.spec.ts"] } diff --git a/package-lock.json b/package-lock.json index f3fb254..712f2c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@noahspan/noahspan-modules", - "version": "1.1.5", + "version": "1.2.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@noahspan/noahspan-modules", - "version": "1.1.5", + "version": "1.2.8", "license": "UNLICENSED", "dependencies": { "@azure/identity": "^4.2.0", @@ -14,9 +14,12 @@ "@microsoft/microsoft-graph-client": "^3.0.7", "@nestjs/common": "^11.0.11", "@nestjs/core": "^11.0.11", + "@nestjs/jwt": "^11.0.0", + "@nestjs/mapped-types": "*", "@nestjs/passport": "^11.0.5", "@nestjs/platform-express": "^11.0.11", "axios": "^1.7.2", + "jwks-rsa": "^3.2.0", "passport": "^0.7.0", "passport-jwt": "^4.0.1", "passport-openidconnect": "^0.1.2", @@ -2369,6 +2372,37 @@ } } }, + "node_modules/@nestjs/jwt": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@nestjs/jwt/-/jwt-11.0.0.tgz", + "integrity": "sha512-v7YRsW3Xi8HNTsO+jeHSEEqelX37TVWgwt+BcxtkG/OfXJEOs6GZdbdza200d6KqId1pJQZ6UPj1F0M6E+mxaA==", + "dependencies": { + "@types/jsonwebtoken": "9.0.7", + "jsonwebtoken": "9.0.2" + }, + "peerDependencies": { + "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0" + } + }, + "node_modules/@nestjs/mapped-types": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.1.0.tgz", + "integrity": "sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw==", + "peerDependencies": { + "@nestjs/common": "^10.0.0 || ^11.0.0", + "class-transformer": "^0.4.0 || ^0.5.0", + "class-validator": "^0.13.0 || ^0.14.0", + "reflect-metadata": "^0.1.12 || ^0.2.0" + }, + "peerDependenciesMeta": { + "class-transformer": { + "optional": true + }, + "class-validator": { + "optional": true + } + } + }, "node_modules/@nestjs/passport": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/@nestjs/passport/-/passport-11.0.5.tgz", @@ -2670,7 +2704,6 @@ "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -2680,7 +2713,6 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -2721,7 +2753,6 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -2733,7 +2764,6 @@ "version": "4.19.1", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.1.tgz", "integrity": "sha512-ej0phymbFLoCB26dbbq5PGScsf2JAJ4IJHjG10LalgUV36XKTmA4GdA+PVllKvRk0sEKt64X8975qFnkSi0hqA==", - "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -2753,8 +2783,7 @@ "node_modules/@types/http-errors": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", @@ -2796,6 +2825,14 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/jsonwebtoken": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.7.tgz", + "integrity": "sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/methods": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz", @@ -2805,14 +2842,12 @@ "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "node_modules/@types/node": { "version": "20.12.12", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", - "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -2860,14 +2895,12 @@ "node_modules/@types/qs": { "version": "6.9.15", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.15.tgz", - "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==", - "dev": true + "integrity": "sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" }, "node_modules/@types/semver": { "version": "7.5.8", @@ -2879,7 +2912,6 @@ "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -2889,7 +2921,6 @@ "version": "1.15.7", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "dev": true, "dependencies": { "@types/http-errors": "*", "@types/node": "*", @@ -6783,6 +6814,14 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/jose": { + "version": "4.15.9", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz", + "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6898,6 +6937,22 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/jwks-rsa": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.2.0.tgz", + "integrity": "sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==", + "dependencies": { + "@types/express": "^4.17.20", + "@types/jsonwebtoken": "^9.0.4", + "debug": "^4.3.4", + "jose": "^4.15.4", + "limiter": "^1.1.5", + "lru-memoizer": "^2.2.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/jws": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", @@ -6947,6 +7002,11 @@ "node": ">= 0.8.0" } }, + "node_modules/limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -6983,6 +7043,11 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -7055,6 +7120,31 @@ "yallist": "^3.0.2" } }, + "node_modules/lru-memoizer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.3.0.tgz", + "integrity": "sha512-GXn7gyHAMhO13WSKrIiNfztwxodVsP8IoZ3XfrJV4yH2x0/OeTO/FIaAHTY5YekdGgW94njfuKmyyt1E0mR6Ug==", + "dependencies": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "6.0.0" + } + }, + "node_modules/lru-memoizer/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-memoizer/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/magic-string": { "version": "0.30.17", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", @@ -9254,8 +9344,7 @@ "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, "node_modules/universalify": { "version": "2.0.1", diff --git a/package.json b/package.json index ee1c118..154b0f2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@noahspan/noahspan-modules", - "version": "1.2.0", + "version": "1.2.8", "description": "", "author": "", "license": "UNLICENSED", @@ -29,9 +29,12 @@ "@microsoft/microsoft-graph-client": "^3.0.7", "@nestjs/common": "^11.0.11", "@nestjs/core": "^11.0.11", + "@nestjs/jwt": "^11.0.0", + "@nestjs/mapped-types": "*", "@nestjs/passport": "^11.0.5", "@nestjs/platform-express": "^11.0.11", "axios": "^1.7.2", + "jwks-rsa": "^3.2.0", "passport": "^0.7.0", "passport-jwt": "^4.0.1", "passport-openidconnect": "^0.1.2", diff --git a/tsconfig.build.json b/tsconfig.build.json index 64f86c6..1b003ad 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -1,4 +1,4 @@ { "extends": "./tsconfig.json", - "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] + "exclude": ["node_modules", "**/*.spec.ts"] }