mirror of
https://github.com/logto-io/logto.git
synced 2025-03-10 22:22:45 -05:00
fix(experience,core): fix SSO register hook event not triggering bug (#5796)
* fix(experience,core): fix SSO register hook event not triggering bug fix the SSO register hook event not triggering bug * chore: update changeset content update changeset content
This commit is contained in:
parent
aec6c779b2
commit
bbd399e157
4 changed files with 49 additions and 17 deletions
29
.changeset/nine-turtles-learn.md
Normal file
29
.changeset/nine-turtles-learn.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
"@logto/experience": patch
|
||||
"@logto/core": patch
|
||||
---
|
||||
|
||||
fix the new user from SSO register hook event not triggering bug
|
||||
|
||||
### Issue
|
||||
|
||||
When a new user registers via SSO, the `PostRegister` interaction hook event is not triggered. `PostSignIn` event is mistakenly triggered instead.
|
||||
|
||||
### Root Cause
|
||||
|
||||
In the SSO `post /api/interaction/sso/:connectionId/registration` API, we update the interaction event to `Register`.
|
||||
However, the hook middleware reads the event from interaction session ahead of the API logic, and the event is not updated resulting in the wrong event being triggered.
|
||||
|
||||
In the current interaction API design, we should mutate the interaction event by calling the `PUT /api/interaction/event` API, instead of updating the event directly in the submit interaction APIs. (Just like the no direct mutation rule for a react state). So we can ensure the correct side effect like logs and hooks are triggered properly.
|
||||
|
||||
All the other sign-in methods are using the `PUT /api/interaction/event` API to update the event. But when implementing the SSO registration API, we were trying to reduce the API requests and directly updated the event in the registration API which will submit the interaction directly.
|
||||
|
||||
### Solution
|
||||
|
||||
Remove the event update logic in the SSO registration API and call the `PUT /api/interaction/event` API to update the event.
|
||||
This will ensure the correct event is triggered in the hook middleware.
|
||||
|
||||
### Action Items
|
||||
|
||||
Align the current interaction API design for now.
|
||||
Need to improve the session/interaction API logic to simplify the whole process.
|
|
@ -18,8 +18,8 @@ import { getInteractionStorage, storeInteractionResult } from './utils/interacti
|
|||
import { getSingleSignOnAuthenticationResult } from './utils/single-sign-on-session.js';
|
||||
import {
|
||||
authorizationUrlPayloadGuard,
|
||||
getSsoAuthorizationUrl,
|
||||
getSsoAuthentication,
|
||||
getSsoAuthorizationUrl,
|
||||
handleSsoAuthentication,
|
||||
registerWithSsoAuthentication,
|
||||
} from './utils/single-sign-on.js';
|
||||
|
@ -134,7 +134,6 @@ export default function singleSignOnRoutes<T extends IRouterParamContext>(
|
|||
koaInteractionHooks(libraries),
|
||||
async (ctx, next) => {
|
||||
const {
|
||||
createLog,
|
||||
assignInteractionHookResult,
|
||||
guard: { params },
|
||||
} = ctx;
|
||||
|
@ -147,13 +146,6 @@ export default function singleSignOnRoutes<T extends IRouterParamContext>(
|
|||
new RequestError({ code: 'auth.forbidden', status: 403 })
|
||||
);
|
||||
|
||||
const registerEventUpdateLog = createLog(`Interaction.Register.Update`);
|
||||
registerEventUpdateLog.append({ event: 'register' });
|
||||
|
||||
// Update the interaction session event to register if no related user account found.
|
||||
// Set the merge flag to true to merge the register event with the existing sso interaction session
|
||||
await storeInteractionResult({ event: InteractionEvent.Register }, ctx, provider, true);
|
||||
|
||||
// Throw 404 if no related session found
|
||||
const authenticationResult = await getSingleSignOnAuthenticationResult(
|
||||
ctx,
|
||||
|
|
|
@ -2,22 +2,23 @@
|
|||
|
||||
import {
|
||||
InteractionEvent,
|
||||
type SignInIdentifier,
|
||||
type BindMfaPayload,
|
||||
type EmailVerificationCodePayload,
|
||||
type PhoneVerificationCodePayload,
|
||||
type SignInIdentifier,
|
||||
type SocialConnectorPayload,
|
||||
type SocialEmailPayload,
|
||||
type SocialPhonePayload,
|
||||
type BindMfaPayload,
|
||||
type VerifyMfaPayload,
|
||||
type WebAuthnRegistrationOptions,
|
||||
type WebAuthnAuthenticationOptions,
|
||||
type WebAuthnRegistrationOptions,
|
||||
} from '@logto/schemas';
|
||||
import { conditional } from '@silverhand/essentials';
|
||||
|
||||
import api from './api';
|
||||
|
||||
const interactionPrefix = '/api/interaction';
|
||||
export const interactionPrefix = '/api/interaction';
|
||||
|
||||
const verificationPath = `verification`;
|
||||
|
||||
type Response = {
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import api from './api';
|
||||
import { InteractionEvent } from '@logto/schemas';
|
||||
|
||||
const ssoPrefix = '/api/interaction/single-sign-on';
|
||||
import api from './api';
|
||||
import { interactionPrefix } from './interaction';
|
||||
|
||||
const ssoPrefix = `${interactionPrefix}/single-sign-on`;
|
||||
|
||||
type Response = {
|
||||
redirectTo: string;
|
||||
|
@ -39,5 +42,12 @@ export const singleSignOnAuthorization = async (connectorId: string, payload: un
|
|||
})
|
||||
.json<Response>();
|
||||
|
||||
export const singleSignOnRegistration = async (connectorId: string) =>
|
||||
api.post(`${ssoPrefix}/${connectorId}/registration`).json<Response>();
|
||||
export const singleSignOnRegistration = async (connectorId: string) => {
|
||||
await api.put(`${interactionPrefix}/event`, {
|
||||
json: {
|
||||
event: InteractionEvent.Register,
|
||||
},
|
||||
});
|
||||
|
||||
return api.post(`${ssoPrefix}/${connectorId}/registration`).json<Response>();
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue