Skip to content

Conversation

@sohail-hashicorp
Copy link
Collaborator

Description

This PR implements the clone and delete button functionality for app token alerts. When an app token is inactive (stale, expired, or revoked) or has permissions with no active grant scopes, users can now clone or delete the token directly from the inline alert banners.

🎟️ Jira ticket

Screenshots (if appropriate)

inactive-app-tokens-demo.mov

How to Test

Inactive Token Alert

  • Navigate to an app token with status expired, stale, or revoked
  • Verify the warning alert displays with Clone and Delete buttons
  • Click Clone -> should navigate to /app-tokens/new?cloneAppToken={id} with form pre-filled
  • Click Delete -> should open modal, type "DELETE" to confirm, token is deleted

Delete Original Banner

  • Start with an inactive token (expired/stale/revoked)
  • Click Clone from the inactive alert
  • Fill out the form and create the new token
  • After creation, verify the "Delete the original app token?" banner appears
  • Verify it shows the original token ID and correct status text ("has expired", "has staled", "has been revoked")
  • Click Delete -> confirm deletion -> banner disappears and original token is deleted

No Active Scopes Alert (Permissions Page)

  • Uncomment the code in /addons/api/mirage/factories/app-tokens.js page
  • Navigate to an app token's Permissions tab
  • Verify the warning alert displays with Clone and Delete buttons
  • Test clone and delete functionality same as above

Checklist

  • I have added before and after screenshots for UI changes
  • I have added JSON response output for API changes
  • I have added steps to reproduce and test for bug fixes in the description
  • I have commented on my code, particularly in hard-to-understand areas
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • I have added a11y-tests label to run a11y audit tests if needed

PCI review checklist

  • I have documented a clear reason for, and description of, the change I am making.
  • If applicable, I've documented a plan to revert these changes if they require more than reverting the pull request.
  • If applicable, I've documented the impact of any changes to security controls.
    Examples of changes to security controls include using new access control methods, adding or removing logging pipelines, etc.

@sohail-hashicorp sohail-hashicorp self-assigned this Feb 5, 2026
@vercel
Copy link

vercel bot commented Feb 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
boundary-ui Ready Ready Preview, Comment Feb 9, 2026 4:26pm
boundary-ui-desktop Ready Ready Preview, Comment Feb 9, 2026 4:26pm

Request Review

@sohail-hashicorp sohail-hashicorp marked this pull request as ready for review February 5, 2026 12:48
@sohail-hashicorp sohail-hashicorp requested a review from a team as a code owner February 5, 2026 12:48
Comment on lines +416 to +417
assert.dom('.hds-modal').isVisible();
assert.dom('.hds-modal__header').containsText('Delete');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we have a data-test attribute we can use here instead of the generic .hds-modal selector?

assert.dom(selectors.DELETE_ORIGINAL_BANNER).isVisible();

// Click the dismiss button
await click('[data-test-delete-original-banner] .hds-dismiss-button');
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we change this to a test selector const?

Comment on lines +21 to +39
@tracked originalTokenWasInactive = false;

/**
* Stores the ID of the original app token being cloned.
* @type {string|null}
*/
@tracked originalTokenId = null;

/**
* Stores the name of the original app token being cloned.
* @type {string|null}
*/
@tracked originalTokenName = null;

/**
* Stores the status of the original app token being cloned.
* @type {string|null}
*/
@tracked originalTokenStatus = null;
Copy link
Collaborator

Choose a reason for hiding this comment

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

non-blocking: I am curious if it would be easier to simply track the original app token model instead of 4 different tracked values? Not saying we should, just wanted to ask if it would clean this up a bit.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants