Skip to content

Conversation

@LinukaAr
Copy link
Member

@LinukaAr LinukaAr commented Dec 12, 2025

Purpose

$subject

Related Issues

Related PRs

Checklist

  • e2e cypress tests locally verified. (for internal contributers)
  • Manual test round performed and verified.
  • UX/UI review done on the final implementation.
  • Documentation provided. (Add links if there are any)
  • Relevant backend changes deployed and verified
  • Unit tests provided. (Add links if there are any)
  • Integration tests provided. (Add links if there are any)

Security checks

Developer Checklist (Mandatory)

  • Complete the Developer Checklist in the related product-is issue to track any behavioral change or migration impact.

Summary by CodeRabbit

  • New Features

    • Added a TOTP authenticator configuration form in the admin UI with localized labels/hints for TOTP enrollment.
  • Behavior Change

    • Settings tab is no longer hidden for TOTP authenticators — it is now skipped only for Magic Link.
  • Chores

    • Integrated TOTP into authenticator flows/exports, added a changeset for package updates, and updated license header and i18n entries.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 12, 2025

Walkthrough

Adds a TOTP authenticator form and exports it; integrates TOTP into authenticator form factories; disables external-authenticators API usage for TOTP; narrows Settings-tab hiding/default-tab skip to Magic Link only; and adds i18n entries and a changeset for TOTP enrollment.

Changes

Cohort / File(s) Summary
TOTP Authenticator Form
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx, features/admin.connections.v1/components/edit/forms/authenticators/index.ts
New TOTPAuthenticatorForm component and public export (FORM_ID etc.). Normalizes keys (dots ↔ underscores), coerces boolean strings, renders enrollment checkbox and submit, and exposes form via authenticators index.
Factory Integrations
features/admin.connections.v1/components/edit/forms/factories/authenticator-form-factory.tsx, features/admin.identity-providers.v1/components/forms/factories/authenticator-form-factory.tsx
Imported TOTPAuthenticatorForm and added switch-case handling for LocalAuthenticatorConstants.AUTHENTICATOR_IDS.TOTP_AUTHENTICATOR_ID to render the TOTP form in both factories.
MFA UI Logic
features/admin.connections.v1/components/edit/edit-multi-factor-authenticator.tsx
Removed TOTP from the condition that hid the Settings tab and from the default-active-index skip logic; comments updated to indicate only Magic Link affects hiding/skipping Settings.
Authenticator Metadata
features/admin.connections.v1/meta/authenticator-meta.ts
Changed TOTP entry’s useAuthenticatorsAPI flag from true to false.
i18n / Translations
modules/i18n/src/models/namespaces/authentication-provider-ns.ts, modules/i18n/src/translations/en-US/portals/authentication-provider.ts
Added totp.enrollUserInAuthenticationFlow with hint and label to forms namespace and English translations.
Changeset / Lint / Manifest
.changeset/lazy-paws-greet.md, .eslintrc.js, package.json
Added changeset for org-level TOTP config; extended license header year regex to include 2026; package manifest reference updated.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Factory as AuthenticatorFormFactory
  participant Form as TOTPAuthenticatorForm
  participant Editor as EditMFAComponent
  participant API as BackendAPI

  User->>Factory: Open authenticator editor (TOTP)
  Factory->>Form: Render with metadata & initialValues
  Form->>Form: Normalize initialValues (keys, booleans)
  User->>Form: Update fields and submit
  Form->>Editor: onSubmit(updated config)
  Editor->>API: Persist authenticator configuration
  API-->>Editor: Acknowledge save
  Editor-->>User: Update UI / close editor
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I hop where dots become underscores neat,

I tick the box so TOTP's complete,
The factory calls which form to show,
Settings hide only for Magic Link’s flow,
A rabbit cheers as configs take seat.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description includes a purpose statement, related issues/PRs, and a partially completed checklist; however, the Purpose section shows only a placeholder "$subject" instead of an actual description of the changes. Replace the "$subject" placeholder in the Purpose section with a clear description of what the PR accomplishes and why the organization-level TOTP configuration UI is being added.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding organization-level TOTP enrollment configuration UI, which aligns with the core changes across multiple files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (2)

189-189: Use strict equality operator.

Replace loose equality (!=) with strict equality (!==) for more predictable behavior and to align with JavaScript best practices.

Apply this diff:

-            if (name != undefined) {
+            if (name !== undefined) {
                 const moderatedName: string = name.replace(/_/g, ".");

238-241: Consider using i18n for accessibility labels.

The ariaLabel attributes use hardcoded English strings. While the visible label for the checkbox uses the i18n system via Trans, consider using i18n for aria labels as well to maintain consistency with the codebase pattern (though the current approach may be acceptable if aria labels are intentionally kept static).

Also applies to: 260-260

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 107ae9c and 148c40d.

📒 Files selected for processing (7)
  • features/admin.connections.v1/components/edit/edit-multi-factor-authenticator.tsx (1 hunks)
  • features/admin.connections.v1/components/edit/forms/authenticators/index.ts (1 hunks)
  • features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (1 hunks)
  • features/admin.connections.v1/components/edit/forms/factories/authenticator-form-factory.tsx (2 hunks)
  • features/admin.connections.v1/constants/connection-ui-constants.ts (1 hunks)
  • features/admin.connections.v1/meta/authenticator-meta.ts (1 hunks)
  • features/admin.identity-providers.v1/components/forms/factories/authenticator-form-factory.tsx (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
features/admin.connections.v1/components/edit/forms/factories/authenticator-form-factory.tsx (1)
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (1)
  • TOTPAuthenticatorForm (113-270)
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (1)
features/admin.identity-providers.v1/models/identity-provider.ts (7)
  • CommonAuthenticatorFormMetaInterface (329-329)
  • CommonAuthenticatorFormInitialValuesInterface (335-335)
  • CommonAuthenticatorFormFieldInterface (347-349)
  • CommonAuthenticatorFormPropertyInterface (341-341)
  • CommonAuthenticatorFormFieldMetaInterface (355-355)
  • CommonPluggableComponentMetaPropertyInterface (357-373)
  • CommonPluggableComponentPropertyInterface (319-323)
features/admin.identity-providers.v1/components/forms/factories/authenticator-form-factory.tsx (1)
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (1)
  • TOTPAuthenticatorForm (113-270)
🔇 Additional comments (11)
features/admin.identity-providers.v1/components/forms/factories/authenticator-form-factory.tsx (2)

23-23: LGTM! Import follows established patterns.

The import correctly references the TOTP authenticator form from the sibling authenticators module.


293-306: LGTM! TOTP authenticator integration follows existing patterns.

The new case correctly mirrors the pattern used by other local authenticators (SMS OTP, Email OTP, Push), passing all required props consistently.

features/admin.connections.v1/components/edit/edit-multi-factor-authenticator.tsx (2)

254-264: LGTM! Settings tab correctly enabled for TOTP.

The condition now appropriately excludes only Magic Link authenticators from the Settings tab, allowing TOTP to surface its configuration UI. The updated comment accurately reflects this narrowed scope.


275-284: LGTM! Default active index logic is consistent.

The change correctly mirrors the tab exclusion logic, ensuring TOTP follows the standard default tab behavior.

features/admin.connections.v1/constants/connection-ui-constants.ts (1)

170-199: LGTM! TOTP constraints are well-defined and reasonable.

The constraint values align with standard TOTP specifications (4-10 digit OTP length, 0-3 window size for time drift tolerance, 1-1440 minute expiry). The structure follows the established pattern used by EMAIL_OTP and SMS_OTP authenticators.

features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (2)

135-175: LGTM! Property name transformation logic is sound.

The effect correctly handles the dot-to-underscore transformation and boolean string parsing, maintaining consistency with the form's internal state management.


183-210: LGTM! Form submission logic correctly reverses the transformation.

The function properly converts underscore-separated names back to dot notation and ensures all values are stringified for submission.

features/admin.connections.v1/components/edit/forms/authenticators/index.ts (1)

28-28: LGTM! Export follows established barrel pattern.

The TOTP authenticator form is correctly exposed through the public API surface.

features/admin.connections.v1/meta/authenticator-meta.ts (1)

373-382: LGTM! API flag correctly aligned with new form integration.

Setting useAuthenticatorsAPI: false for TOTP is consistent with similar authenticators (Email OTP, SMS OTP, FIDO, Push) and properly enables the local form flow introduced in this PR.

features/admin.connections.v1/components/edit/forms/factories/authenticator-form-factory.tsx (2)

42-43: LGTM! Import organized correctly.

The TOTPAuthenticatorForm import is properly placed alongside other authenticator form imports.


249-262: LGTM! TOTP case follows established factory pattern.

The implementation correctly mirrors the SMS_OTP authenticator case, passing all standard props and maintaining consistency across the factory.

@codecov
Copy link

codecov bot commented Dec 12, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 55.88%. Comparing base (69bd0fa) to head (bcbe9b1).
⚠️ Report is 51 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #9494   +/-   ##
=======================================
  Coverage   55.88%   55.88%           
=======================================
  Files          42       42           
  Lines        1020     1020           
  Branches      231      231           
=======================================
  Hits          570      570           
  Misses        450      450           
Flag Coverage Δ
@wso2is/core 55.88% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🧹 Nitpick comments (1)
features/admin.identity-providers.v1/components/forms/factories/authenticator-form-factory.tsx (1)

19-19: New import looks fine; ensure package dependency boundaries are intended.
Just verify @wso2is/admin.connections.v1 is an allowed dependency for @wso2is/admin.identity-providers.v1 (to avoid unintended coupling/version skew).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 148c40d and 29473ea.

📒 Files selected for processing (2)
  • features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (1 hunks)
  • features/admin.identity-providers.v1/components/forms/factories/authenticator-form-factory.tsx (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (1)
features/admin.identity-providers.v1/models/identity-provider.ts (6)
  • CommonAuthenticatorFormMetaInterface (329-329)
  • CommonAuthenticatorFormInitialValuesInterface (335-335)
  • CommonAuthenticatorFormFieldInterface (347-349)
  • CommonAuthenticatorFormPropertyInterface (341-341)
  • CommonPluggableComponentMetaPropertyInterface (357-373)
  • CommonPluggableComponentPropertyInterface (319-323)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (5)
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (5)

98-103: Fix type mismatch in error validation interface.

TOTP_EnrolUserInAuthenticationFlow is declared as a required string but line 211 assigns undefined to it, creating a type mismatch. Since validation errors are conditionally returned, this field should be optional.

Apply this diff:

 export interface TOTPAuthenticatorFormErrorValidationsInterface {
     /**
      * Enable progressive enrollment.
      */
-    TOTP_EnrolUserInAuthenticationFlow: string;
+    TOTP_EnrolUserInAuthenticationFlow?: string;
 }

38-73: Make unused props optional to align interface with implementation.

triggerSubmit, enableSubmitButton, and showCustomProperties are declared as required but never destructured or used in the component. The comment on line 66 explicitly states showCustomProperties is "Not implemented ATM." This creates a contract mismatch where callers must provide values that the component ignores.

Apply this diff to make these props optional:

-    triggerSubmit: boolean;
+    triggerSubmit?: boolean;
-    enableSubmitButton: boolean;
+    enableSubmitButton?: boolean;
-    showCustomProperties: boolean;
+    showCustomProperties?: boolean;

178-200: Add null safety and remove redundant conditional in getUpdatedConfigurations.

Line 189 has a redundant conditional (isBoolean(value) ? value.toString() : value.toString()) where both branches call toString(). More critically, toString() will throw if value is null or undefined, which can occur as form fields evolve.

Apply this diff:

         for (const [ name, value ] of Object.entries(values)) {
-            if (name != undefined) {
+            if (name) {
                 const moderatedName: string = name.replace(/_/g, ".");

+                if (value === null || value === undefined) {
+                    continue;
+                }
+
                 properties.push({
                     name: moderatedName,
-                    value: isBoolean(value) ? value.toString() : value.toString()
+                    value: String(value)
                 });
             }
         }

117-124: triggerSubmit prop is not destructured or implemented.

While triggerSubmit is declared in the props interface (line 59), it's never destructured here or used anywhere in the component. If parent components need to trigger form submission externally, this will fail silently.

To implement external form submission, add a ref and a useEffect to watch triggerSubmit:

 const {
     metadata,
     initialValues: originalInitialValues,
     onSubmit,
     readOnly,
     isSubmitting,
+    triggerSubmit,
+    enableSubmitButton,
     ["data-testid"]: testId
 } = props;

 const { t } = useTranslation();
+const formRef = useRef<any>();

+useEffect(() => {
+    if (triggerSubmit && formRef.current) {
+        formRef.current.submitForm();
+    }
+}, [ triggerSubmit ]);

Then attach the ref to the Form component:

 <Form
+    ref={ formRef }
     id={ FORM_ID }

Also destructure enableSubmitButton to use it on the submit button (line 253).


128-130: Remove unused state and fix type-unsafe initialization.

Line 129 declares setFormFields but the state is never read—only written at line 168, making it dead code. Additionally, both state variables are initialized with undefined, violating their type contracts (TOTPAuthenticatorFormFieldsInterface and TOTPAuthenticatorFormInitialValuesInterface don't allow undefined).

Apply this diff:

-    // This can be used when `meta` support is there.
-    const [ , setFormFields ] = useState<TOTPAuthenticatorFormFieldsInterface>(undefined);
-    const [ initialValues, setInitialValues ] = useState<TOTPAuthenticatorFormInitialValuesInterface>(undefined);
+    const [ initialValues, setInitialValues ] = useState<TOTPAuthenticatorFormInitialValuesInterface | undefined>(undefined);

And remove the call to setFormFields at line 168:

-        setFormFields(resolvedFormFields);
         setInitialValues(resolvedInitialValues);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29473ea and 3bad494.

📒 Files selected for processing (1)
  • features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (1)
features/admin.identity-providers.v1/models/identity-provider.ts (7)
  • CommonAuthenticatorFormMetaInterface (329-329)
  • CommonAuthenticatorFormInitialValuesInterface (335-335)
  • CommonAuthenticatorFormFieldInterface (347-349)
  • CommonAuthenticatorFormPropertyInterface (341-341)
  • CommonAuthenticatorFormFieldMetaInterface (355-355)
  • CommonPluggableComponentMetaPropertyInterface (357-373)
  • CommonPluggableComponentPropertyInterface (319-323)

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds organization-level TOTP (Time-based One-Time Password) enrollment configuration UI to the authentication provider settings. It enables administrators to configure progressive enrollment for TOTP devices, allowing users to enroll their devices during the login flow.

Changes:

  • Added a new TOTP authenticator form component with a progressive enrollment checkbox setting
  • Integrated the TOTP form into both identity provider and connection authenticator form factories
  • Updated TOTP authenticator metadata to use the local form instead of the external authenticators API
  • Fixed settings tab visibility to show settings for TOTP authenticator (previously excluded)

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
totp-authenticator-form.tsx New form component for TOTP authenticator configuration with progressive enrollment option
authenticator-form-factory.tsx (identity-providers) Added TOTP case to render the new TOTP form
authenticator-form-factory.tsx (connections) Added TOTP case to render the new TOTP form
index.ts Exported the new TOTP authenticator form
authenticator-meta.ts Changed useAuthenticatorsAPI flag to false for TOTP to use local form
edit-multi-factor-authenticator.tsx Removed TOTP from settings tab exclusion list to enable settings UI

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @.changeset/lazy-paws-greet.md:
- Line 6: Update the changeset note to fix grammar by replacing the phrase "a
org level config to govern TOTP" with "an org-level config to govern TOTP" so it
uses the correct article and hyphenation.
♻️ Duplicate comments (3)
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (3)

126-151: Avoid spreading null and guard optional property names.

{ ...resolvedFormFields } and { ...resolvedInitialValues } will throw when the first property is processed because both are initialized to null. Also, value.name is optional, so replace() can crash when it’s missing.

🐛 Proposed fix
-        let resolvedFormFields: TOTPAuthenticatorFormFieldsInterface = null;
-        let resolvedInitialValues: TOTPAuthenticatorFormInitialValuesInterface = null;
+        let resolvedFormFields: Partial<TOTPAuthenticatorFormFieldsInterface> = {};
+        let resolvedInitialValues: TOTPAuthenticatorFormInitialValuesInterface = {
+            TOTP_EnrolUserInAuthenticationFlow: false
+        };
@@
-            const moderatedName: string = value.name.replace(/\./g, "_");
+            const rawName: string = value.name ?? value.key ?? "";
+            if (!rawName) {
+                return;
+            }
+            const moderatedName: string = rawName.replace(/\./g, "_");

168-175: Guard nullish values before toString() in submission mapping.

If any field value is null/undefined, value.toString() will throw. Normalize safely.

✅ Proposed fix
-        for (const [ name, value ] of Object.entries(values)) {
-            if (name !== undefined) {
+        for (const [ name, value ] of Object.entries(values ?? {})) {
+            if (!name || value === null || value === undefined) {
+                continue;
+            }
                 const moderatedName: string = name.replace(/_/g, ".");
 
                 properties.push({
                     name: moderatedName,
-                    value: value.toString()
+                    value: String(value)
                 });
             }
         }

83-88: Align validation return type with interface.

TOTP_EnrolUserInAuthenticationFlow is declared as a required string, but validateForm() returns undefined. Make it optional or return an empty object.

🔧 Suggested fix
 export interface TOTPAuthenticatorFormErrorValidationsInterface {
     /**
      * Enable progressive enrollment.
      */
-    TOTP_EnrolUserInAuthenticationFlow: string;
+    TOTP_EnrolUserInAuthenticationFlow?: string;
 }
@@
-        const errors: TOTPAuthenticatorFormErrorValidationsInterface = {
-            TOTP_EnrolUserInAuthenticationFlow: undefined
-        };
-
-        return errors;
+        return {};

Also applies to: 192-199

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx`:
- Around line 139-151: In getUpdatedConfigurations, avoid calling
value.toString() unguarded; replicate the pattern used in other forms by
checking isBoolean(value) before converting — i.e., when building
CommonPluggableComponentPropertyInterface entries in the loop over
Object.entries(values), set value to isBoolean(value) ? value.toString() : value
so null/undefined or non-boolean values won't cause a runtime error; reference
the getUpdatedConfigurations function and the properties array where the push
occurs and use the existing isBoolean helper.
♻️ Duplicate comments (3)
.changeset/lazy-paws-greet.md (1)

7-7: Fix changeset grammar (“an org-level”).

Minor wording polish for the release note.

✏️ Suggested edit
-Introduce a org level config to govern TOTP
+Introduce an org-level config to govern TOTP
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (2)

116-120: Guard optional value.name before replace().

CommonPluggableComponentPropertyInterface.name is optional; calling replace() can throw when it’s missing.

🛠️ Suggested fix
-            const moderatedName: string = value.name.replace(/\./g, "_");
+            const rawName: string = value.name ?? value.key;
+            if (!rawName) {
+                return;
+            }
+            const moderatedName: string = rawName.replace(/\./g, "_");

103-131: Guard against optional name property before calling .replace().

value.name is optional in CommonPluggableComponentPropertyInterface but line 120 calls .replace() without a null/undefined check, causing a runtime crash. Additionally, the early return at line 111 leaves initialValues as undefined, and resolvedInitialValues starts as null, leading to inconsistent state passed to the Form. Initialize with a safe default object and ensure all code paths set valid values.

🛠️ Suggested fix
+    const defaultInitialValues: TOTPAuthenticatorFormInitialValuesInterface = {
+        TOTP_EnrolUserInAuthenticationFlow: false
+    };
-
-    const [ initialValues, setInitialValues ] = useState<TOTPAuthenticatorFormInitialValuesInterface>(undefined);
+    const [ initialValues, setInitialValues ] =
+        useState<TOTPAuthenticatorFormInitialValuesInterface>(defaultInitialValues);
@@
-        if (isEmpty(originalInitialValues?.properties)) {
-            return;
-        }
-
-        let resolvedInitialValues: TOTPAuthenticatorFormInitialValuesInterface = null;
+        if (isEmpty(originalInitialValues?.properties)) {
+            setInitialValues(defaultInitialValues);
+            return;
+        }
+
+        let resolvedInitialValues: TOTPAuthenticatorFormInitialValuesInterface = {
+            ...defaultInitialValues
+        };
+
-            const moderatedName: string = value.name.replace(/\./g, "_");
+            const moderatedName: string = (value.name ?? "").replace(/\./g, "_");
🧹 Nitpick comments (1)
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (1)

172-176: Use i18n label instead of hardcoded text.

You already added the label in i18n; wire it here so localization stays consistent.

♻️ Suggested change
-                label="Enable TOTP device progressive enrollment"
+                label={ t("authenticationProvider:forms.authenticatorSettings.totp.enrollUserInAuthenticationFlow.label") }

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx`:
- Around line 110-121: The loop over originalInitialValues.properties uses
value.name without checking for undefined which can throw; update the code in
the forEach that computes moderatedName (inside
TOTPAuthenticatorFormInitialValues resolution) to guard against missing name by
using optional chaining or a default (e.g. const moderatedName = (value.name ??
"") .replace(/\./g, "_") or skip entries with no name), and ensure you handle
the resulting key being empty (skip or use a safe fallback) before assigning
into resolvedInitialValues; keep all other logic (parsing "true"/"false") the
same and reference the variables/methods: originalInitialValues.properties,
value (CommonAuthenticatorFormPropertyInterface), moderatedName, and
resolvedInitialValues.
♻️ Duplicate comments (3)
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (3)

165-183: Use i18n for the checkbox label.

The label prop on line 168 is hardcoded in English while the hint correctly uses Trans for i18n. For consistency and localization support, the label should also use t().

Proposed fix
             <Field.Checkbox
                 ariaLabel="Enable TOTP device progressive enrollment"
                 name="TOTP_EnrolUserInAuthenticationFlow"
-                label="Enable TOTP device progressive enrollment"
+                label={ t("authenticationProvider:forms.authenticatorSettings.totp.enrollUserInAuthenticationFlow.label") }
                 hint={

Ensure a corresponding i18n key is added to the translation files.


99-99: Fix type mismatch: state initialized with undefined but type doesn't allow it.

TOTPAuthenticatorFormInitialValuesInterface doesn't include undefined, yet the state is initialized with undefined. This causes a TypeScript type mismatch.

Proposed fix
-    const [ initialValues, setInitialValues ] = useState<TOTPAuthenticatorFormInitialValuesInterface>(undefined);
+    const [ initialValues, setInitialValues ] = useState<TOTPAuthenticatorFormInitialValuesInterface | undefined>(undefined);

137-146: Add null guard before value.toString() to prevent runtime crash.

If a form field value is null or undefined, calling value.toString() will throw. Add a defensive check consistent with other authenticator forms in the codebase.

🐛 Proposed fix
         for (const [ name, value ] of Object.entries(values)) {
             if (name !== undefined) {
                 const moderatedName: string = name.replace(/_/g, ".");

+                if (value === null || value === undefined) {
+                    continue;
+                }
+
                 properties.push({
                     name: moderatedName,
-                    value: value.toString()
+                    value: String(value)
                 });
             }
         }
🧹 Nitpick comments (1)
features/admin.connections.v1/components/edit/forms/authenticators/totp-authenticator-form.tsx (1)

70-75: Consider removing the unused error validation interface.

TOTPAuthenticatorFormErrorValidationsInterface is exported but there's no validation logic in this component. If validation is not planned, this interface is dead code and could be removed to improve maintainability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants