Skip to content

Commit 66d68d8

Browse files
authored
Merge pull request #305 from brionmario/refactor-thunder-flows
Fix `SignUp` issues in AsgardeoV2
2 parents c16c850 + 0852c2e commit 66d68d8

File tree

4 files changed

+117
-11
lines changed

4 files changed

+117
-11
lines changed

.changeset/old-banks-hope.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@asgardeo/react': patch
3+
---
4+
5+
Fix Sign up

packages/react/src/components/presentation/auth/AuthOptionFactory.tsx

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,6 @@ const createAuthComponentFromFlow = (
130130
): ReactElement | null => {
131131
const key: string | number = options.key || component.id;
132132

133-
if (authType === 'signin') {
134-
console.log('Creating sign-in component for:', component);
135-
}
136-
137133
switch (component.type) {
138134
case EmbeddedFlowComponentType.TextInput:
139135
case EmbeddedFlowComponentType.PasswordInput:
@@ -173,9 +169,8 @@ const createAuthComponentFromFlow = (
173169
if (options.onSubmit) {
174170
const formData: Record<string, any> = {};
175171
Object.keys(formValues).forEach(field => {
176-
if (formValues[field]) {
177-
formData[field] = formValues[field];
178-
}
172+
// Include all values, even empty strings, to ensure proper submission
173+
formData[field] = formValues[field];
179174
});
180175
options.onSubmit(component, formData, shouldSkipValidation);
181176
}

packages/react/src/components/presentation/auth/SignUp/v2/BaseSignUp.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -334,8 +334,12 @@ const BaseSignUpContent: FC<BaseSignUpProps> = ({
334334
const processComponents = (comps: any[]) => {
335335
comps.forEach(component => {
336336
if (component.type === EmbeddedFlowComponentType.TextInput) {
337+
// Use component.ref (mapped identifier) as the field name instead of component.id
338+
// This ensures form field names match what the input components use
339+
const fieldName = component.ref || component.id;
340+
337341
fields.push({
338-
name: component.id,
342+
name: fieldName,
339343
required: component.required || false,
340344
initialValue: '',
341345
validator: (value: string) => {
@@ -457,7 +461,7 @@ const BaseSignUpContent: FC<BaseSignUpProps> = ({
457461
const payload: EmbeddedFlowExecuteRequestPayload = {
458462
...(currentFlow.flowId && {flowId: currentFlow.flowId}),
459463
flowType: (currentFlow as any).flowType || 'REGISTRATION',
460-
...(component.id && {action: component.id}),
464+
...(component.id && {actionId: component.id}),
461465
inputs: filteredInputs,
462466
} as any;
463467

packages/react/src/utils/v2/flowTransformer.ts

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,101 @@ export interface FlowTransformOptions {
7979
resolveTranslations?: boolean;
8080
}
8181

82+
/**
83+
* Create a mapping from ref to identifier based on data.inputs array.
84+
* This handles cases where meta.components use 'ref' to reference inputs,
85+
* and data.inputs contain the actual 'identifier' field.
86+
*
87+
* @param response - The flow response object
88+
* @returns Map of ref to identifier
89+
*/
90+
const createInputRefMapping = (response: any): Map<string, string> => {
91+
const mapping = new Map<string, string>();
92+
93+
if (response?.data?.inputs && Array.isArray(response.data.inputs)) {
94+
response.data.inputs.forEach((input: any) => {
95+
if (input.ref && input.identifier) {
96+
mapping.set(input.ref, input.identifier);
97+
}
98+
});
99+
}
100+
101+
return mapping;
102+
};
103+
104+
/**
105+
* Create a mapping from action ref to nextNode based on data.actions array.
106+
* This handles cases where meta.components reference actions by ref,
107+
* and data.actions contain the actual nextNode field for routing.
108+
*
109+
* @param response - The flow response object
110+
* @returns Map of action ref to nextNode
111+
*/
112+
const createActionRefMapping = (response: any): Map<string, string> => {
113+
const mapping = new Map<string, string>();
114+
115+
if (response?.data?.actions && Array.isArray(response.data.actions)) {
116+
response.data.actions.forEach((action: any) => {
117+
if (action.ref && action.nextNode) {
118+
mapping.set(action.ref, action.nextNode);
119+
}
120+
});
121+
}
122+
123+
return mapping;
124+
};
125+
126+
/**
127+
* Apply input ref mapping to components recursively.
128+
* This ensures that component.ref values are mapped to the correct identifier
129+
* from data.inputs, enabling proper form submission.
130+
*
131+
* @param components - Array of components to transform
132+
* @param refMapping - Map of ref to identifier
133+
* @param actionMapping - Map of action ref to nextNode
134+
* @returns Transformed components with correct identifiers and action references
135+
*/
136+
const applyInputRefMapping = (
137+
components: EmbeddedFlowComponent[],
138+
refMapping: Map<string, string>,
139+
actionMapping: Map<string, string>,
140+
): EmbeddedFlowComponent[] => {
141+
return components.map(component => {
142+
const transformedComponent = {...component} as EmbeddedFlowComponent & {actionRef?: string};
143+
144+
// If this component has a ref that maps to an identifier, update it
145+
if (transformedComponent.ref && refMapping.has(transformedComponent.ref)) {
146+
transformedComponent.ref = refMapping.get(transformedComponent.ref);
147+
}
148+
149+
// If this is an action component, map its id to the nextNode
150+
// Store the nextNode reference as actionRef property for later use
151+
if (
152+
transformedComponent.type === 'ACTION' &&
153+
transformedComponent.id &&
154+
actionMapping.has(transformedComponent.id)
155+
) {
156+
transformedComponent.actionRef = actionMapping.get(transformedComponent.id);
157+
}
158+
159+
// Recursively apply to nested components
160+
if (transformedComponent.components && Array.isArray(transformedComponent.components)) {
161+
transformedComponent.components = applyInputRefMapping(
162+
transformedComponent.components,
163+
refMapping,
164+
actionMapping,
165+
);
166+
}
167+
168+
return transformedComponent;
169+
});
170+
};
171+
82172
/**
83173
* Transform and resolve translations in components from flow response.
84174
* This function extracts components from the response meta structure and optionally resolves
85-
* any translation strings within them.
175+
* any translation strings within them. It also handles mapping of input refs to identifiers
176+
* and action refs to nextNode values.
86177
*
87178
* @param response - The flow response object containing components in meta structure
88179
* @param t - Translation function from useTranslation hook
@@ -98,7 +189,18 @@ export const transformComponents = (
98189
return [];
99190
}
100191

101-
const components: EmbeddedFlowComponent[] = response.data.meta.components;
192+
let components: EmbeddedFlowComponent[] = response.data.meta.components;
193+
194+
// Create mapping from ref to identifier based on data.inputs
195+
const refMapping = createInputRefMapping(response);
196+
197+
// Create mapping from action ref to nextNode based on data.actions
198+
const actionMapping = createActionRefMapping(response);
199+
200+
// Apply ref and action mapping if there are any mappings
201+
if (refMapping.size > 0 || actionMapping.size > 0) {
202+
components = applyInputRefMapping(components, refMapping, actionMapping);
203+
}
102204

103205
return resolveTranslations ? resolveTranslationsInArray(components, t) : components;
104206
};

0 commit comments

Comments
 (0)