Skip to content

Commit 13326e0

Browse files
committed
fix(journey-client): create JourneyLoginFailure step and handle LoginFailure case
1 parent f66b1fd commit 13326e0

4 files changed

Lines changed: 44 additions & 20 deletions

File tree

.changeset/journey-loginfailure-on-error-code.md renamed to .changeset/whole-mangos-find.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
'@forgerock/journey-client': patch
33
---
44

5-
Return `JourneyLoginFailure` by hitting the previously-unreached `LoginFailure` branch when `start()`/`next()` receives a failure payload with a `code`.
5+
Return `JourneyLoginFailure` by hitting the previously-unreached `LoginFailure` branch when `start()`/`next()` receives a failure payload with a login failure `code`

packages/journey-client/src/lib/client.store.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @vitest-environment node
22
/*
3-
* Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
3+
* Copyright (c) 2025-2026 Ping Identity Corporation. All rights reserved.
44
*
55
* This software may be modified and distributed under the terms
66
* of the MIT license. See the LICENSE file for details.

packages/journey-client/src/lib/client.store.ts

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
2+
* Copyright (c) 2025-2026 Ping Identity Corporation. All rights reserved.
33
*
44
* This software may be modified and distributed under the terms
55
* of the MIT license. See the LICENSE file for details.
@@ -16,7 +16,6 @@ import {
1616
import type { GenericError } from '@forgerock/sdk-types';
1717
import type { ActionTypes, RequestMiddleware } from '@forgerock/sdk-request-middleware';
1818
import type { Step } from '@forgerock/sdk-types';
19-
import type { FetchBaseQueryError } from '@reduxjs/toolkit/query';
2019

2120
import { createJourneyStore } from './client.store.utils.js';
2221
import { configSlice } from './config.slice.js';
@@ -156,17 +155,11 @@ export async function journey<ActionType extends ActionTypes = ActionTypes>({
156155

157156
const self: JourneyClient = {
158157
start: async (options?: StartParam) => {
159-
const { data, error } = await store.dispatch(journeyApi.endpoints.start.initiate(options));
158+
const { data } = await store.dispatch(journeyApi.endpoints.start.initiate(options));
160159
if (data) {
161160
return createJourneyObject(data);
162161
}
163162

164-
const errorData = (error as FetchBaseQueryError | undefined)?.data;
165-
const errorStep = errorData as Step | undefined;
166-
if (errorStep?.code !== undefined) {
167-
return createJourneyObject(errorStep);
168-
}
169-
170163
const genericError: GenericError = {
171164
error: 'no_response_data',
172165
message: 'No data received from server when starting journey',
@@ -179,19 +172,11 @@ export async function journey<ActionType extends ActionTypes = ActionTypes>({
179172
* Submits the current Step payload to the authentication API and retrieves the next JourneyStep in the journey.
180173
*/
181174
next: async (step: JourneyStep, options?: NextOptions) => {
182-
const { data, error } = await store.dispatch(
183-
journeyApi.endpoints.next.initiate({ step, options }),
184-
);
175+
const { data } = await store.dispatch(journeyApi.endpoints.next.initiate({ step, options }));
185176
if (data) {
186177
return createJourneyObject(data);
187178
}
188179

189-
const errorData = (error as FetchBaseQueryError | undefined)?.data;
190-
const errorStep = errorData as Step | undefined;
191-
if (errorStep?.code !== undefined) {
192-
return createJourneyObject(errorStep);
193-
}
194-
195180
const genericError: GenericError = {
196181
error: 'no_response_data',
197182
message: 'No data received from server when submitting step',

packages/journey-client/src/lib/journey.api.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ interface Extras {
8989
logger: ReturnType<typeof loggerFn>;
9090
}
9191

92+
// Only treat these numeric codes as login failures coming back in the Step payload.
93+
const LOGIN_FAILURE_CODES = [400, 401, 403, 412, 423, 429];
94+
9295
export const journeyApi = createApi({
9396
reducerPath: 'journeyReducer',
9497
baseQuery: fetchBaseQuery({
@@ -133,6 +136,24 @@ export const journeyApi = createApi({
133136
return result as QueryReturnValue<unknown, FetchBaseQueryError, FetchBaseQueryMeta>;
134137
});
135138

139+
/**
140+
* If the endpoint returned an HTTP error whose body is an AM Step with a
141+
* login-failure code, treat it as successful data so callers receive the
142+
* Step via the `data` path (keeps downstream logic simpler).
143+
*/
144+
if ('error' in response) {
145+
const errorData = (response.error as FetchBaseQueryError | undefined)?.data as
146+
| Step
147+
| undefined;
148+
if (errorData && errorData.code && LOGIN_FAILURE_CODES.includes(errorData.code)) {
149+
return { data: errorData } as QueryReturnValue<
150+
Step,
151+
FetchBaseQueryError,
152+
FetchBaseQueryMeta
153+
>;
154+
}
155+
}
156+
136157
return response as QueryReturnValue<Step, FetchBaseQueryError, FetchBaseQueryMeta>;
137158
},
138159
}),
@@ -162,6 +183,24 @@ export const journeyApi = createApi({
162183
return result as QueryReturnValue<unknown, FetchBaseQueryError, FetchBaseQueryMeta>;
163184
});
164185

186+
/**
187+
* If the endpoint returned an HTTP error whose body is an AM Step with a
188+
* login-failure code, treat it as successful data so callers receive the
189+
* Step via the `data` path (keeps downstream logic simpler).
190+
*/
191+
if ('error' in response) {
192+
const errorData = (response.error as FetchBaseQueryError | undefined)?.data as
193+
| Step
194+
| undefined;
195+
if (errorData && errorData.code && LOGIN_FAILURE_CODES.includes(errorData.code)) {
196+
return { data: errorData } as QueryReturnValue<
197+
Step,
198+
FetchBaseQueryError,
199+
FetchBaseQueryMeta
200+
>;
201+
}
202+
}
203+
165204
return response as QueryReturnValue<Step, FetchBaseQueryError, FetchBaseQueryMeta>;
166205
},
167206
}),

0 commit comments

Comments
 (0)