Skip to content
Merged

Dev #1063

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
## 🔗 Jira Ticket

> Replace with your ticket link — required before requesting review.

[MIGRATION-XXXX](https://contentstack.atlassian.net/browse/MIGRATION-XXXX)

---

## 📋 PR Type

<!-- Check all that apply -->

- [ ] ✨ Feature
- [ ] 🐛 Bug Fix
- [ ] 🔥 Hotfix
- [ ] ♻️ Refactor
- [ ] 🧹 Chore / Dependency Update
- [ ] 📝 Documentation

---

## 📝 Description

<!-- A clear and concise summary of what this PR does and why. -->

### What changed?

<!-- Describe the changes in bullet points -->

-

### Why?

<!-- Context, motivation, or problem this solves -->

---

## 🧩 Affected Areas

<!-- Check all modules/layers that are touched -->

- [ ] `api` — Node.js backend
- [ ] `ui` — React frontend
- [ ] `upload-api` — Upload API server
- [ ] `docker` / `docker-compose`
- [ ] CI / GitHub Actions workflows
- [ ] Environment variables / config
- [ ] Other: <!-- specify -->

---

## 🧪 How to Test

<!-- Step-by-step instructions for the reviewer to verify this change -->

1.
2.
3.

**Expected result:**

---

## 📸 Screenshots / Recordings

<!-- If UI changes are involved, attach before/after screenshots or a short screen recording -->

| Before | After |
|--------|-------|
| | |

---

## 🔗 Related PRs / Dependencies

<!-- Link any PRs this depends on or is related to -->

-

---

## ✅ Author Checklist

> Complete this before moving the PR out of Draft.

- [ ] Branch follows naming convention: `feature/`, `bugfix/`, or `hotfix/` + 5–30 lowercase chars
- [ ] Jira ticket linked above
- [ ] Self-reviewed the diff — no debug logs, commented-out code, or TODOs left in
- [ ] `.env` / `example.env` updated if new environment variables were added
- [ ] No sensitive credentials or secrets committed
- [ ] Existing tests pass locally (`npm test`)
- [ ] New tests written (or not applicable — explain why)
- [ ] `README.md` / docs updated if behaviour changed
- [ ] Talisman pre-push scan passes (no secrets flagged)

---

## 👀 Reviewer Notes

<!-- Anything specific you'd like reviewers to focus on or be cautious about -->

---

> **Migration v2** · [Docs](https://github.com/contentstack/migration-v2#readme) · [Issues](https://github.com/contentstack/migration-v2/issues)
12 changes: 6 additions & 6 deletions api/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@
"@contentstack/cli": "^1.58.0",
"@contentstack/cli-utilities": "^1.18.3",
"@contentstack/json-rte-serializer": "^3.0.5",
"@contentstack/marketplace-sdk": "^1.5.0",
"@contentstack/marketplace-sdk": "^1.5.2",
"@emnapi/core": "1.9.1",
"@emnapi/runtime": "1.9.1",
"@emnapi/wasi-threads": "1.2.0",
"@wordpress/block-serialization-default-parser": "^5.39.0",
"axios": "^1.15.2",
"axios": "^1.16.0",
"cheerio": "^1.2.0",
"chokidar": "^3.6.0",
"cors": "^2.8.5",
Expand Down
1 change: 1 addition & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"react-redux": "^9.1.2",
"react-router": "^7.0.0",
"react-router-dom": "^7.0.0",
"react-toastify": "npm:@contentstack/react-toastify@6.1.5",
"redux-persist": "^6.0.0",
"sass": "^1.68.0",
"socket.io-client": "^4.7.5",
Expand Down
33 changes: 31 additions & 2 deletions ui/src/pages/Login/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
Icon
} from '@contentstack/venus-components';
import { Field as FinalField, Form as FinalForm } from 'react-final-form';
import { toast as toastify } from 'react-toastify';

// Utilities
import {
Expand Down Expand Up @@ -45,6 +46,24 @@ const SSO_SUCCESS_REDIRECT_MS = 2800;
/** Must match oauth-callback-html `OAUTH_CALLBACK_POSTMESSAGE_SOURCE` in the API. */
const SSO_OAUTH_POSTMESSAGE_SOURCE = 'cs-migration-oauth-callback';

/**
* Stable id for the SSO "select this organization" warning toast so we can
* dismiss it explicitly when the SSO flow ends (success / cancel / error /
* unmount) instead of leaving it stuck on screen.
*/
const SSO_ORG_INSTRUCTION_NOTIFICATION_ID = 'sso-org-instruction';

/** Safety auto-close for the SSO org instruction toast (ms). */
const SSO_ORG_INSTRUCTION_AUTO_CLOSE_MS = 5000;

const dismissSsoOrgInstruction = () => {
try {
toastify.dismiss(SSO_ORG_INSTRUCTION_NOTIFICATION_ID);
} catch {
/* no-op: dismissing a missing/already-closed toast must not throw */
}
};

const isOrgMismatchSsoMessage = (message: string) =>
message.includes('Organization mismatch');

Expand All @@ -64,6 +83,10 @@ const Login: FC<IProps> = () => {
clearTimeout(ssoPollTimerRef.current);
ssoPollTimerRef.current = null;
}
// The org-instruction toast is only relevant while the SSO flow is in
// progress. Whenever the flow ends (success, cancel, error, timeout) we
// funnel through cancelSsoPoll, so dismiss the toast here too.
dismissSsoOrgInstruction();
};

const fetchData = async () => {
Expand All @@ -84,6 +107,9 @@ const Login: FC<IProps> = () => {
if (ssoSuccessRedirectTimerRef.current) {
clearTimeout(ssoSuccessRedirectTimerRef.current);
}
// Don't leave the SSO org-instruction toast stranded if the user
// navigates away mid-flow.
dismissSsoOrgInstruction();
};
}, []);

Expand Down Expand Up @@ -341,15 +367,17 @@ const Login: FC<IProps> = () => {
}

if (appConfig?.organization?.name) {
dismissSsoOrgInstruction();
Notification({
notificationId: SSO_ORG_INSTRUCTION_NOTIFICATION_ID,
notificationContent: {
text: `In Contentstack, select organization "${appConfig.organization.name}" when you install or authorize this app. Choosing a different organization will cause SSO to fail.`,
text: `In Contentstack, select organization "${appConfig?.organization?.name}" when you install or authorize this app. Choosing a different organization will cause SSO to fail.`,
},
type: 'warning',
notificationProps: {
hideProgressBar: true,
position: 'bottom-center',
autoClose: false,
autoClose: SSO_ORG_INSTRUCTION_AUTO_CLOSE_MS,
},
});
}
Expand All @@ -361,6 +389,7 @@ const Login: FC<IProps> = () => {
if (appConfig?.user?.uid) {
startSSOPolling(appConfig?.user?.uid, ssoWindow);
} else {
dismissSsoOrgInstruction();
failureNotification('Missing user information in SSO configuration');
setIsLoading(false);
}
Expand Down
Loading