Skip to content

Commit

Permalink
Merge pull request #33 from flowcore-io/feature/add-token-to-request-…
Browse files Browse the repository at this point in the history
…and-create-token-decorator

feat: added token decorator
  • Loading branch information
jbiskur authored Dec 9, 2024
2 parents 71b110a + fe7f2f6 commit e0491bd
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 11 deletions.
6 changes: 2 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ name: Test

on:
push:
branches-ignore: [ "main" ]
branches-ignore: ["main"]

env:
NODE_VERSION: ">=18.12.1"

jobs:

test:

runs-on: ubuntu-latest

steps:
Expand All @@ -30,7 +28,7 @@ jobs:
run: yarn lint
- name: Start Keycloak
run: |
docker-compose -f test/docker/docker-compose.yaml up -d
docker compose -f test/docker/docker-compose.yaml up -d
chmod +x test/docker/await-testing.sh
test/docker/await-testing.sh
- name: Test
Expand Down
5 changes: 3 additions & 2 deletions src/library/decorator/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./authenticated-user.decorator";
export * from "./public.decorator";
export * from "./resource-roles.decorator";
export * from "./realm-roles.decorator";
export * from "./authenticated-user.decorator";
export * from "./resource-roles.decorator";
export * from "./token.decorator";
21 changes: 21 additions & 0 deletions src/library/decorator/token.decorator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { createParamDecorator, type ExecutionContext } from "@nestjs/common";
import { OidcProtectService } from "../oidc-protect/oidc-protect.service";

export interface TokenOptions {
required?: boolean;
storedIn?: string;
}

export const Token = createParamDecorator<TokenOptions>(
async (data, ctx: ExecutionContext) => {
const request = await OidcProtectService.getRequest(ctx);

const { required = true, storedIn = "token" } = data || {};

if (!request[storedIn] && required) {
throw new Error("Token not found");
}

return request[storedIn];
},
);
11 changes: 6 additions & 5 deletions src/library/guard/auth.guard.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { InjectLogger, LoggerService } from "@flowcore/microservice";
import {
CanActivate,
ExecutionContext,
Injectable,
UnauthorizedException,
UnauthorizedException
} from "@nestjs/common";
import { InjectLogger, LoggerService } from "@flowcore/microservice";
import dayjs from "dayjs";
import { OidcProtectService } from "../oidc-protect/oidc-protect.service";
import { Reflector } from "@nestjs/core";
import dayjs from "dayjs";
import { PUBLIC_OPERATION_KEY } from "../decorator/public.decorator";
import { OidcProtectService } from "../oidc-protect/oidc-protect.service";

@Injectable()
export class AuthGuard implements CanActivate {
Expand Down Expand Up @@ -56,7 +56,7 @@ export class AuthGuard implements CanActivate {
}

request.authenticatedUser = decodedToken;

request.token = token;
return true;
}

Expand All @@ -78,6 +78,7 @@ export class AuthGuard implements CanActivate {
}

request.authenticatedUser = decodedToken;
request.token = token;
return true;
} catch (e) {
return true;
Expand Down
7 changes: 7 additions & 0 deletions test/fixtures/test.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Public,
RealmRoles,
ResourceRoles,
Token,
} from "../../src";
import { CLIENT_ROLE, REALM_ROLE } from "./keycloak/keycloak-prep.service";

Expand Down Expand Up @@ -39,4 +40,10 @@ export class TestResolver {
public authenticatedUser(@AuthenticatedUser() user: any): string {
return user.preferred_username;
}

@RealmRoles([REALM_ROLE])
@Query(() => String, { name: "token" })
public token(@Token() token: string): string {
return token;
}
}
20 changes: 20 additions & 0 deletions test/oidc-protect.module.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,26 @@ describe("OIDC Protect Module", () => {
);
});

it("should get access to token", async () => {
const token = await (
await app.resolve(KeycloakPrepService)
).getUserToken(UserType.TEST_USER);

const decoded: any = jwtDecode(token);

Check warning on line 294 in test/oidc-protect.module.spec.ts

View workflow job for this annotation

GitHub Actions / test

'decoded' is assigned a value but never used

const response = await queryGraphQLEndpoint(
app,
gql`
query {
token
}
`,
token,
);

expect(response.body.data.token).toBe(token);
});

it("should return forbidden with no access to resource role", async () => {
const token = await (
await app.resolve(KeycloakPrepService)
Expand Down
1 change: 1 addition & 0 deletions test/test.schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ type Query {
realmRole: String!
resourceRole: String!
authenticatedUser: String!
token: String!
testPerson: TestPerson!
}

0 comments on commit e0491bd

Please sign in to comment.