mirror of
https://github.com/ToolJet/ToolJet
synced 2026-04-21 21:47:17 +00:00
* test: verify pre-commit hook * fix: clean up code formatting and improve readability across multiple components * chore: update subproject commit reference in frontend/ee * chore: update eslint to version 9.26.0 and remove unused dependencies from package.json fix: update submodule reference in server/ee * chore: refactor ESLint configuration and add quiet linting script; update components to disable specific ESLint rules * chore: add GitHub Copilot review instructions for App Builder team Covers backward compatibility rules, styling conventions, state management, resolution system, widget definitions, and common review flags. * chore: add review instructions for App Builder, Data Migrations, Server Widget Config, Widget Components, and Widget Config * Enhance TypeScript support in frontend configuration - Added TypeScript parser and linting rules to ESLint configuration. - Updated Babel configuration to include TypeScript preset. - Modified package.json and package-lock.json to include TypeScript and related dependencies. - Introduced tsconfig.json for TypeScript compiler options. - Updated Webpack configuration to support .ts and .tsx file extensions. - Adjusted linting and formatting scripts to include TypeScript files. * chore: update TypeScript ESLint packages and subproject commits --------- Co-authored-by: kavinvenkatachalam <kavin.saratha@gmail.com> Co-authored-by: Johnson Cherian <johnsonc.dev@gmail.com>
88 lines
2.7 KiB
JavaScript
88 lines
2.7 KiB
JavaScript
import React, { useEffect } from 'react';
|
|
import useRouter from '@/_hooks/use-router';
|
|
import config from 'config';
|
|
import toast from 'react-hot-toast';
|
|
import './embed-loader.scss';
|
|
import Loader from '@/ToolJetUI/Loader/Loader';
|
|
|
|
// In-memory PAT token store
|
|
let inMemoryPatToken = null;
|
|
|
|
export function setPatToken(patToken) {
|
|
inMemoryPatToken = patToken;
|
|
}
|
|
|
|
export function getPatToken() {
|
|
if (inMemoryPatToken) return inMemoryPatToken;
|
|
// Fallback to window.name (persists across same-tab navigations)
|
|
if (window.name && window.name.length > 0) {
|
|
inMemoryPatToken = window.name;
|
|
return inMemoryPatToken;
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
export default function EmbedAppRedirect() {
|
|
const router = useRouter();
|
|
const { appId } = router.query;
|
|
|
|
useEffect(() => {
|
|
// 🔐 Ensure the page is embedded
|
|
if (window.self === window.top) {
|
|
// Not inside an iframe
|
|
toast.error('This page must be embedded inside a parent application.');
|
|
return;
|
|
}
|
|
const token = new URLSearchParams(window.location.search).get('personal-access-token');
|
|
|
|
if (!token || typeof appId !== 'string') {
|
|
parent?.postMessage({ type: 'TJ_EMBED_APP_LOGOUT', error: 400, message: 'Missing token or appId' }, '*');
|
|
return;
|
|
}
|
|
|
|
const initiateSession = async () => {
|
|
try {
|
|
const res = await fetch(`${config.apiUrl}/ext/users/session`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
credentials: 'include',
|
|
body: JSON.stringify({ appId, accessToken: token }),
|
|
});
|
|
if (!res.ok) {
|
|
if (res.status === 401 || res.status === 403) {
|
|
toast.error('Your pat is expired. Please refresh or contact your admin.');
|
|
// 🔔 Show toast if token is expired or invalid
|
|
parent?.postMessage(
|
|
{
|
|
type: 'TJ_EMBED_APP_LOGOUT',
|
|
error: res.status,
|
|
message: 'Your pat is expired. Please refresh or contact your admin.',
|
|
},
|
|
'*'
|
|
);
|
|
}
|
|
return;
|
|
}
|
|
|
|
const result = await res.json();
|
|
// ✅ Store PAT in memory
|
|
setPatToken(result.signedPat);
|
|
window.name = result.signedPat;
|
|
window.location.href = `applications/${appId}`;
|
|
} catch (error) {
|
|
parent?.postMessage({ type: 'TJ_EMBED_APP_LOGOUT', error: 500, message: 'Network error' }, '*');
|
|
}
|
|
};
|
|
|
|
initiateSession();
|
|
}, [appId]);
|
|
|
|
return (
|
|
<div className="embed-loader">
|
|
<div className="embed-loader__content">
|
|
<Loader width={30} absolute={false} />
|
|
<div className="embed-loader__text">Loading embedded app</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|