Skip to content

Commit

Permalink
refactor(iam): move logic from controller down to use-case
Browse files Browse the repository at this point in the history
  • Loading branch information
Gi-jutsu committed Jul 22, 2024
1 parent 73cb896 commit 35aedf6
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 27 deletions.
2 changes: 2 additions & 0 deletions src/application.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import { Logger, Module, OnApplicationShutdown } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { HealthCheckHttpController } from "./shared-kernel/use-cases/health-check/http.controller.js";
import { SignInWithOAuthProviderHttpController } from "@identity-and-access/use-cases/sign-in-with-oauth-provider/http.controller.js";
import { SignInWithOAuthProviderUseCase } from "@identity-and-access/use-cases/sign-in-with-oauth-provider/use-case.js";

@Module({
imports: [ConfigModule.forRoot()],
controllers: [
HealthCheckHttpController,
SignInWithOAuthProviderHttpController,
],
providers: [SignInWithOAuthProviderUseCase],
})
export class ApplicationModule implements OnApplicationShutdown {
private readonly logger = new Logger(ApplicationModule.name);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { describe, expect, it } from "vitest";

describe("SignInWithOAuthProviderUseCase", () => {
it("should initiate the OAuth flow by redirecting to the IDP's authorization endpoint", async () => {
// Act
const response = await fetch(
"http://localhost:8080/identity-and-access/oauth/google"
);
it.each`
provider | expectedRedirectUrl
${"google"} | ${"https://accounts.google.com/v3/signin/identifier"}
`(
"should initiate the $provider OAuth flow by redirecting to the IDP's authorization endpoint",
async ({ provider, expectedRedirectUrl }) => {
// Act
const response = await fetch(
`http://localhost:8080/identity-and-access/oauth/${provider}`
);

// Assert
expect(response.redirected).toBe(true);
expect(response.url).toMatch(
"https://accounts.google.com/v3/signin/identifier"
);
});
// Assert
expect(response.redirected).toBe(true);
expect(response.url).toMatch(expectedRedirectUrl);
}
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,19 @@ import {
Get,
HttpCode,
HttpStatus,
Param,
Redirect,
} from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { SignInWithOAuthProviderUseCase } from "./use-case.js";

@Controller()
export class SignInWithOAuthProviderHttpController {
constructor(private readonly config: ConfigService) {}
constructor(private readonly useCase: SignInWithOAuthProviderUseCase) {}

@Get("/identity-and-access/oauth/google")
@Get("/identity-and-access/oauth/:provider")
@HttpCode(HttpStatus.PERMANENT_REDIRECT)
@Redirect()
async signInWithGoogle() {
const baseAuthorizationUrl = `https://accounts.google.com/o/oauth2/v2/auth`;
const authorizationUrlParameters = new URLSearchParams({
client_id: await this.config.getOrThrow("OAUTH_GOOGLE_CLIENT_ID"),
redirect_uri:
"http://localhost:8080/identity-and-access/oauth/google/callback",
response_type: "code",
scope: "email",
});

return {
url: `${baseAuthorizationUrl}?${authorizationUrlParameters}`,
};
async signInWithGoogle(@Param("provider") provider: string) {
return await this.useCase.execute({ provider });
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { Injectable, NotImplementedException } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";

@Injectable()
export class SignInWithOAuthProviderUseCase {
constructor(private readonly config: ConfigService) {}

async execute(command: SignInWithOAuthProviderCommand) {
if (command.provider !== "google") {
throw new NotImplementedException();
}

return this.handleSignInWithGoogle();
}

async handleSignInWithGoogle() {
const baseAuthorizationUrl = `https://accounts.google.com/o/oauth2/v2/auth`;
const authorizationUrlParameters = new URLSearchParams({
client_id: await this.config.getOrThrow("OAUTH_GOOGLE_CLIENT_ID"),
redirect_uri:
"http://localhost:8080/identity-and-access/oauth/google/callback",
response_type: "code",
scope: "email",
});

return {
url: `${baseAuthorizationUrl}?${authorizationUrlParameters}`,
};
}
}

type SignInWithOAuthProviderCommand = {
provider: string;
};

0 comments on commit 35aedf6

Please sign in to comment.