From 69d9fad3d42a09ad12a6155a2822187bc69effed Mon Sep 17 00:00:00 2001 From: Diptesh Choudhuri Date: Sat, 27 Jul 2024 18:25:32 +0530 Subject: [PATCH] fix(backend,frontend): register/login flow for oidc --- apps/backend/src/miscellaneous.rs | 19 +++++++++++ apps/frontend/app/routes/api.auth.tsx | 33 +++++++++++-------- apps/frontend/app/routes/auth.tsx | 4 +-- libs/generated/src/graphql/backend/gql.ts | 4 +-- libs/generated/src/graphql/backend/graphql.ts | 15 +++++++++ libs/graphql/src/backend/queries/combined.gql | 4 +++ 6 files changed, 61 insertions(+), 18 deletions(-) diff --git a/apps/backend/src/miscellaneous.rs b/apps/backend/src/miscellaneous.rs index 8780de27b2..f958af5da2 100644 --- a/apps/backend/src/miscellaneous.rs +++ b/apps/backend/src/miscellaneous.rs @@ -1080,6 +1080,16 @@ impl MiscellaneousQuery { let service = gql_ctx.data_unchecked::>(); service.get_oidc_token(code).await } + + /// Get user by OIDC issuer ID. + async fn user_by_oidc_issuer_id( + &self, + gql_ctx: &Context<'_>, + oidc_issuer_id: String, + ) -> Result> { + let service = gql_ctx.data_unchecked::>(); + service.user_by_oidc_issuer_id(oidc_issuer_id).await + } } #[derive(Default)] @@ -7166,6 +7176,15 @@ GROUP BY m.id; } } + async fn user_by_oidc_issuer_id(&self, oidc_issuer_id: String) -> Result> { + let user = User::find() + .filter(user::Column::OidcIssuerId.eq(oidc_issuer_id)) + .one(&self.db) + .await? + .map(|u| u.id); + Ok(user) + } + async fn invalidate_import_jobs(&self) -> Result<()> { let all_jobs = ImportReport::find() .filter(import_report::Column::WasSuccess.is_null()) diff --git a/apps/frontend/app/routes/api.auth.tsx b/apps/frontend/app/routes/api.auth.tsx index d2a07e842f..abc6bf69ca 100644 --- a/apps/frontend/app/routes/api.auth.tsx +++ b/apps/frontend/app/routes/api.auth.tsx @@ -5,6 +5,7 @@ import { LoginUserDocument, RegisterErrorVariant, RegisterUserDocument, + UserByOidcIssuerIdDocument, } from "@ryot/generated/graphql/backend/graphql"; import { z } from "zod"; import { zx } from "zodix"; @@ -30,21 +31,25 @@ export const loader = unstable_defineLoader(async ({ request }) => { email: getOidcToken.email, issuerId: getOidcToken.subject, }; - const [_, { registerUser }] = await Promise.all([ - getCachedCoreDetails(), - serverGqlService.request(RegisterUserDocument, { - input: { data: { oidc: oidcInput } }, - }), - ]); - if ( - registerUser.__typename === "RegisterError" && - registerUser.error === RegisterErrorVariant.Disabled - ) { - return redirectWithToast($path("/auth"), { - message: "Registration is disabled", - type: "error", - }); + const { userByOidcIssuerId } = await serverGqlService.request( + UserByOidcIssuerIdDocument, + { oidcIssuerId: oidcInput.issuerId }, + ); + if (!userByOidcIssuerId) { + const { registerUser } = await serverGqlService.request( + RegisterUserDocument, + { input: { data: { oidc: oidcInput } } }, + ); + if ( + registerUser.__typename === "RegisterError" && + registerUser.error === RegisterErrorVariant.Disabled + ) + return redirectWithToast($path("/auth"), { + message: "Registration is disabled", + type: "error", + }); } + await getCachedCoreDetails(); const { loginUser } = await serverGqlService.request(LoginUserDocument, { input: { oidc: oidcInput }, }); diff --git a/apps/frontend/app/routes/auth.tsx b/apps/frontend/app/routes/auth.tsx index aafeefaa79..b7c1a58dc9 100644 --- a/apps/frontend/app/routes/auth.tsx +++ b/apps/frontend/app/routes/auth.tsx @@ -186,7 +186,7 @@ export const action = unstable_defineAction(async ({ request }) => { headers: await createToastHeaders({ message, type: "error" }), }); }, - getOauthRedirectUrl: async () => { + getOidcRedirectUrl: async () => { const { getOidcRedirectUrl } = await serverGqlService.request( GetOidcRedirectUrlDocument, ); @@ -287,7 +287,7 @@ export default function Page() {