Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add authentication with multiple jwt providers #694

Merged
merged 42 commits into from
Feb 24, 2022
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
62feeb9
refactor(aws-creds): move to aws-creds folder
Jan 31, 2022
5e85979
feat(auth): basic auth guard
MeStrak Jan 31, 2022
748f8b4
feat: begin support mutli jwt providers
MeStrak Feb 2, 2022
11d871a
feat: load from config
MeStrak Feb 2, 2022
76531c9
feat: get ExtractJwt func from string
MeStrak Feb 3, 2022
7474658
Add auth config to .env files
MeStrak Feb 3, 2022
1123176
test: add first auth e2e test
MeStrak Feb 4, 2022
03de5f8
chore: lint cleanup
MeStrak Feb 4, 2022
cf83380
style: run formatter
MeStrak Feb 4, 2022
4dc0524
test: fix src path
MeStrak Feb 4, 2022
164e8a6
stylr: run formatter
MeStrak Feb 4, 2022
8c75e86
test(auth e2e): valid JWT test
MeStrak Feb 4, 2022
d04df8c
style: fix linting errors
MeStrak Feb 4, 2022
f5ec1a6
test(auth e2e): add negative JWT tests
MeStrak Feb 5, 2022
2e42421
feat(config): make auth_config required
MeStrak Feb 5, 2022
0905e4c
test(load): correct auth config string
MeStrak Feb 6, 2022
5e40261
chore: exclude test code duplication detection
MeStrak Feb 7, 2022
345f35a
test: export testing costs
MeStrak Feb 7, 2022
cb8b9d9
feat: auth funcName and args as array
MeStrak Feb 7, 2022
487edd9
feat: Joi validation of auth config
MeStrak Feb 8, 2022
ec331e6
style: lint and format
MeStrak Feb 8, 2022
f2843cc
feat: improve joi auth config validation
MeStrak Feb 9, 2022
d74ab67
feat: update to AUTH_CONFIG_SECRET
MeStrak Feb 9, 2022
069789b
feat: remove async from jwt validate
MeStrak Feb 9, 2022
5b0c396
feat: coerce Joi object from JSON
MeStrak Feb 9, 2022
879565c
style: lint and format
MeStrak Feb 9, 2022
43d7487
docs: create security page
MeStrak Feb 9, 2022
4f2627a
feat: add passportJwtSecret support
MeStrak Feb 11, 2022
1a1a443
docs: add missing comma
MeStrak Feb 11, 2022
f2fe455
style: lint and format
MeStrak Feb 11, 2022
d96da7c
test: add initial getAuthConfig tests
MeStrak Feb 11, 2022
81ea110
test: add secretOrKey and some negative tests
MeStrak Feb 11, 2022
dd27d75
test: auth config
MeStrak Feb 13, 2022
4530512
test: add jwt.strategy unit test
MeStrak Feb 13, 2022
f8609e1
feat: load algorithms as array
MeStrak Feb 15, 2022
85bee88
test: add jwks e2e test
MeStrak Feb 15, 2022
b3075f4
docs: link to security page
MeStrak Feb 15, 2022
09f0331
chore: update example .envs with auth_config
MeStrak Feb 15, 2022
15e9be5
ci: fix test auth_config
MeStrak Feb 15, 2022
6bca22f
ci: revert previous change
MeStrak Feb 15, 2022
cb97336
test: install nock dependency
MeStrak Feb 15, 2022
56eeb98
feat(auth): conf and move to node 16
over-flo79 Feb 23, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/k6-load-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ jobs:
AWS_S3_ENDPOINT: http://localhost:4566
AWS_ACCESS_KEY_ID: dummy
AWS_SECRET_ACCESS_KEY: dummy
AUTH_CONFIG: '{"config":[{"jwtFromRequest":"ExtractJwt.fromAuthHeaderAsBearerToken()","ignoreExpiration":false,"secretOrKey":"VALID_SECRET_KEY"},{"jwtFromRequest":"ExtractJwt.fromAuthHeaderAsBearerToken()","ignoreExpiration":false,"secretOrKey":"another_secret_key"}]}'
services:
mongo:
image: mongo
Expand Down
1 change: 1 addition & 0 deletions example.env
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ AWS_S3_ENDPOINT = http://localstack:4566/
AWS_BUCKET_NAME = demo-bucket

EXAMPLE_TEST = test
AUTH_CONFIG = {"config":[{"jwtFromRequest":"ExtractJwt.fromAuthHeaderAsBearerToken()","ignoreExpiration":false,"secretOrKey":"a_secret_key"},{"jwtFromRequest":"ExtractJwt.fromAuthHeaderAsBearerToken()","ignoreExpiration":false,"secretOrKey":"a_secret_keyx"}]}
3 changes: 2 additions & 1 deletion example.rep.env
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ COGNITO_REGION
COGNITO_IDENTITY_POOL_ID
AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
AWS_S3_ENDPOINT
AWS_BUCKET_NAME
AWS_BUCKET_NAME
AUTH_CONFIG = {"config":[{"jwtFromRequest":"ExtractJwt.fromAuthHeaderAsBearerToken()","ignoreExpiration":false,"secretOrKey":"a_secret_key"},{"jwtFromRequest":"ExtractJwt.fromAuthHeaderAsBearerToken()","ignoreExpiration":false,"secretOrKey":"a_secret_keyx"}]}
151 changes: 146 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,23 @@
"test:unit:cov": "jest --coverage --forceExit --detectOpenHandles",
"test:unit:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:integration": "jest --config jest-integration.json --runInBand --forceExit",
"test:e2e": "jest --config jest-e2e.json --runInBand --forceExit",
"test:e2e": "jest --config jest-e2e.json --verbose --runInBand --forceExit",
"test:e2e:debug": "node --inspect-brk=0.0.0.0 -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand --config jest-e2e.json",
"docs:build": "vuepress build docs",
"docs:dev": "vuepress dev docs"
},
"dependencies": {
"@apollo/gateway": "0.44.1",
"@instana/collector": "1.137.2",
"@mestrak/passport-multi-jwt": "0.0.3",
"@nestjs/axios": "0.0.3",
"@nestjs/common": "8.2.3",
"@nestjs/config": "1.1.5",
"@nestjs/core": "8.2.3",
"@nestjs/graphql": "9.1.2",
"@nestjs/jwt": "^8.0.0",
"@nestjs/mongoose": "8.0.1",
"@nestjs/passport": "8.0.1",
"@nestjs/passport": "^8.0.1",
"@nestjs/platform-fastify": "8.2.3",
"@nestjs/platform-socket.io": "8.2.3",
"@nestjs/terminus": "8.0.3",
Expand Down Expand Up @@ -67,6 +69,8 @@
"lodash": "4.17.21",
"mongoose": "5.13.13",
"mongoose-cast-aggregation": "0.2.1",
"passport": "^0.5.2",
"passport-jwt": "^4.0.0",
"reflect-metadata": "0.1.13",
"request": "2.88.2",
"rimraf": "3.0.2",
Expand Down
1 change: 1 addition & 0 deletions schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ type WhispCount {
type Query {
whispById(id: String!): Whisp
whisps(limit: Int, sort: JSONObject, filter: JSONObject): [Whisp!]
whispsAuthBeta(limit: Int, sort: JSONObject, filter: JSONObject): [Whisp!]
countWhisps(group: JSONObject, filter: [JSONObject!]): [WhispCount!]!
webhooks: [Webhook!]
tagGroups(tagGroup: TagGroupInputType!): [TagGroup!]
Expand Down
1 change: 1 addition & 0 deletions sonarcloud.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sonar.cpd.exclusions=tests/**/*.spec.ts
4 changes: 3 additions & 1 deletion src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { MongooseModule } from '@nestjs/mongoose';

import { TerminusModule } from '@nestjs/terminus';
import { ApolloServerPluginLandingPageLocalDefault } from 'apollo-server-core';
import { AWSCredsModule } from './auth/aws-creds.module';
import { AWSCredsModule } from './aws-creds/aws-creds.module';
import { ConfigModule } from './config/config.module';
import { DistributionModule } from './distribution/distribution.module';
import { EventModule } from './event/event.module';
Expand All @@ -20,6 +20,7 @@ import { ConfigService } from './config/config.service';
import { WebhookModule } from './webhook/webhook.module';
import { TagModule } from './tag/tag.module';
import { HealthController } from './health/health.controller';
import { AuthModule } from './auth/auth.module';

@Module({
imports: [
Expand Down Expand Up @@ -52,6 +53,7 @@ import { HealthController } from './health/health.controller';
DistributionModule,
EventModule,
WebhookModule,
AuthModule,
],
providers: [AppService],
controllers: [AppController, HealthController],
Expand Down
18 changes: 18 additions & 0 deletions src/auth/auth.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Module } from '@nestjs/common';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { JwtStrategy } from './jwt.strategy';
import { ConfigModule } from '../config/config.module';

@Module({
imports: [
PassportModule,
ConfigModule,
JwtModule.register({
MeStrak marked this conversation as resolved.
Show resolved Hide resolved
secret: 'some_secret_thing',
signOptions: { expiresIn: '60s' },
}),
],
providers: [JwtStrategy],
})
export class AuthModule {}
12 changes: 12 additions & 0 deletions src/auth/gql-jwt-auth.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* eslint-disable class-methods-use-this */
import { ExecutionContext, Injectable } from '@nestjs/common';
import { GqlExecutionContext } from '@nestjs/graphql';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class GqlJwtAuthGuard extends AuthGuard('jwt') {
getRequest(context: ExecutionContext) {
const ctx = GqlExecutionContext.create(context);
return ctx.getContext().req;
}
}
5 changes: 5 additions & 0 deletions src/auth/jwt-auth.guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
Loading