From dd837835a9937a1c9ab82c9643aafd63d277b10c Mon Sep 17 00:00:00 2001 From: Mihovil Ilakovac Date: Tue, 27 Aug 2024 12:27:26 +0200 Subject: [PATCH] Fix onBeforeLogin hook params (#2254) --- .../templates/sdk/wasp/server/auth/hooks.ts | 4 +++ .../server/src/auth/providers/oauth/user.ts | 14 ++++++---- .../waspComplexTest/.wasp/out/.waspchecksums | 4 +-- .../out/sdk/wasp/dist/server/auth/hooks.d.ts | 4 +++ .../.wasp/out/sdk/wasp/server/auth/hooks.ts | 4 +++ .../server/src/auth/providers/oauth/user.ts | 14 ++++++---- web/docs/auth/auth-hooks.md | 27 ++++++++----------- 7 files changed, 43 insertions(+), 28 deletions(-) diff --git a/waspc/data/Generator/templates/sdk/wasp/server/auth/hooks.ts b/waspc/data/Generator/templates/sdk/wasp/server/auth/hooks.ts index 6b5824dec8..67b1f2431c 100644 --- a/waspc/data/Generator/templates/sdk/wasp/server/auth/hooks.ts +++ b/waspc/data/Generator/templates/sdk/wasp/server/auth/hooks.ts @@ -97,6 +97,10 @@ type OnBeforeLoginHookParams = { * Provider ID object that contains the provider name and the provide user ID. */ providerId: ProviderId + /** + * User that is trying to log in. + */ + user: Awaited>['user'] /** * Request object that can be used to access the incoming request. */ diff --git a/waspc/data/Generator/templates/server/src/auth/providers/oauth/user.ts b/waspc/data/Generator/templates/server/src/auth/providers/oauth/user.ts index 5733fb8943..799e615439 100644 --- a/waspc/data/Generator/templates/server/src/auth/providers/oauth/user.ts +++ b/waspc/data/Generator/templates/server/src/auth/providers/oauth/user.ts @@ -81,17 +81,21 @@ async function getAuthIdFromProviderDetails({ if (existingAuthIdentity) { const authId = existingAuthIdentity.{= authFieldOnAuthIdentityEntityName =}.id + // NOTE: Fetching the user to pass it to the login hooks - it's a bit wasteful + // but we wanted to keep the onAfterLoginHook params consistent for all auth providers. + const auth = await findAuthWithUserBy({ id: authId }) + // NOTE: We are calling login hooks here even though we didn't log in the user yet. // It's because we have access to the OAuth tokens here and we want to pass them to the hooks. // We could have stored the tokens temporarily and called the hooks after the session is created, // but this keeps the implementation simpler. // The downside of this approach is that we can't provide the session to the login hooks, but this is // an okay trade-off because OAuth tokens are more valuable to users than the session ID. - await onBeforeLoginHook({ req, providerId }) - - // NOTE: Fetching the user to pass it to the onAfterLoginHook - it's a bit wasteful - // but we wanted to keep the onAfterLoginHook params consistent for all auth providers. - const auth = await findAuthWithUserBy({ id: authId }) + await onBeforeLoginHook({ + req, + providerId, + user: auth.user, + }) // NOTE: check the comment above onBeforeLoginHook for the explanation why we call onAfterLoginHook here. await onAfterLoginHook({ diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums index d935f01b32..0d9eb6a1ec 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/.waspchecksums @@ -529,7 +529,7 @@ "file", "../out/sdk/wasp/server/auth/hooks.ts" ], - "1112920618b85e793ed676fd2987cf1dde59820e9a3a58bc43208f86c752b3a2" + "1626df1c652b4f5d5f6a64c6537bae422243e62c867e668c16968738fd9637b1" ], [ [ @@ -977,7 +977,7 @@ "file", "server/src/auth/providers/oauth/user.ts" ], - "088acfe21e47d5a4a68faefa898c0174529e1b5a76dd86d32a0fce7d2a781f44" + "0798bdc8635f62e693d7bb4df5ab5ee4ec08a59b43cee3ce14094fd9ae19c89e" ], [ [ diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/auth/hooks.d.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/auth/hooks.d.ts index 866269e469..fe3999de1d 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/auth/hooks.d.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/dist/server/auth/hooks.d.ts @@ -68,6 +68,10 @@ type OnBeforeLoginHookParams = { * Provider ID object that contains the provider name and the provide user ID. */ providerId: ProviderId; + /** + * User that is trying to log in. + */ + user: Awaited>['user']; /** * Request object that can be used to access the incoming request. */ diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/auth/hooks.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/auth/hooks.ts index af64f6df9d..bb61fe8b95 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/auth/hooks.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/sdk/wasp/server/auth/hooks.ts @@ -96,6 +96,10 @@ type OnBeforeLoginHookParams = { * Provider ID object that contains the provider name and the provide user ID. */ providerId: ProviderId + /** + * User that is trying to log in. + */ + user: Awaited>['user'] /** * Request object that can be used to access the incoming request. */ diff --git a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/server/src/auth/providers/oauth/user.ts b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/server/src/auth/providers/oauth/user.ts index 88c2c33eac..c252b60f1a 100644 --- a/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/server/src/auth/providers/oauth/user.ts +++ b/waspc/e2e-test/test-outputs/waspComplexTest-golden/waspComplexTest/.wasp/out/server/src/auth/providers/oauth/user.ts @@ -80,17 +80,21 @@ async function getAuthIdFromProviderDetails({ if (existingAuthIdentity) { const authId = existingAuthIdentity.auth.id + // NOTE: Fetching the user to pass it to the login hooks - it's a bit wasteful + // but we wanted to keep the onAfterLoginHook params consistent for all auth providers. + const auth = await findAuthWithUserBy({ id: authId }) + // NOTE: We are calling login hooks here even though we didn't log in the user yet. // It's because we have access to the OAuth tokens here and we want to pass them to the hooks. // We could have stored the tokens temporarily and called the hooks after the session is created, // but this keeps the implementation simpler. // The downside of this approach is that we can't provide the session to the login hooks, but this is // an okay trade-off because OAuth tokens are more valuable to users than the session ID. - await onBeforeLoginHook({ req, providerId }) - - // NOTE: Fetching the user to pass it to the onAfterLoginHook - it's a bit wasteful - // but we wanted to keep the onAfterLoginHook params consistent for all auth providers. - const auth = await findAuthWithUserBy({ id: authId }) + await onBeforeLoginHook({ + req, + providerId, + user: auth.user, + }) // NOTE: check the comment above onBeforeLoginHook for the explanation why we call onAfterLoginHook here. await onAfterLoginHook({ diff --git a/web/docs/auth/auth-hooks.md b/web/docs/auth/auth-hooks.md index 2ae1e8ed6a..69937590ef 100644 --- a/web/docs/auth/auth-hooks.md +++ b/web/docs/auth/auth-hooks.md @@ -309,12 +309,7 @@ app myApp { ``` ```js title="src/auth/hooks.js" -export const onBeforeOAuthRedirect = async ({ - url, - oauth, - prisma, - req, -}) => { +export const onBeforeOAuthRedirect = async ({ url, oauth, prisma, req }) => { console.log('query params before oAuth redirect', req.query) // Saving query params for later use in onAfterSignup or onAfterLogin hooks @@ -388,7 +383,7 @@ app myApp { ```js title="src/auth/hooks.js" import { HttpError } from 'wasp/server' -export const onBeforeLogin = async ({ providerId, prisma, req }) => { +export const onBeforeLogin = async ({ providerId, user, prisma, req }) => { if ( providerId.providerName === 'email' && providerId.providerUserId === 'some@email.com' @@ -417,6 +412,7 @@ import type { OnBeforeLoginHook } from 'wasp/server/auth' export const onBeforeLogin: OnBeforeLoginHook = async ({ providerId, + user, prisma, req, }) => { @@ -733,12 +729,7 @@ Wasp ignores this hook's **return value**. ```js title="src/auth/hooks.js" -export const onBeforeOAuthRedirect = async ({ - url, - oauth, - prisma, - req, -}) => { +export const onBeforeOAuthRedirect = async ({ url, oauth, prisma, req }) => { // Hook code goes here return { url } @@ -776,11 +767,11 @@ The hook receives an object as **input** with the following properties: The `oauth` object has the following fields: - - `uniqueRequestId: string` + - `uniqueRequestId: string` - The unique request ID for the OAuth flow (you might know it as the `state` parameter in OAuth.) + The unique request ID for the OAuth flow (you might know it as the `state` parameter in OAuth.) - You can use the unique request ID to save data (e.g. request query params) that you can later use in the `onAfterSignup` or `onAfterLogin` hooks. + You can use the unique request ID to save data (e.g. request query params) that you can later use in the `onAfterSignup` or `onAfterLogin` hooks. - Plus the [common hook input](#common-hook-input) @@ -819,6 +810,10 @@ The hook receives an object as **input** with the following properties: - [`providerId: ProviderId`](#providerid-fields) +- `user: User` + + The user that is trying to log in. + - Plus the [common hook input](#common-hook-input) Wasp ignores this hook's **return value**.