Compare commits
3 Commits
684b98bd0e
...
1d49161a05
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d49161a05 | ||
|
|
bf157687d4 | ||
|
|
7cb78f13c0 |
@@ -216,10 +216,7 @@ export const Layout: React.FC<{ children: React.ReactNode }> = ({ children }) =>
|
|||||||
{localStorage.getItem('ctms_super_admin_token') && (
|
{localStorage.getItem('ctms_super_admin_token') && (
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (returnToSuperAdmin()) {
|
returnToSuperAdmin();
|
||||||
window.location.hash = '#/super-admin';
|
|
||||||
window.location.reload();
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
className="w-full flex items-center justify-center gap-2 py-2 px-3 bg-zinc-900 dark:bg-brand-yellow text-white dark:text-zinc-950 rounded-lg text-xs font-bold hover:opacity-90 transition-colors"
|
className="w-full flex items-center justify-center gap-2 py-2 px-3 bg-zinc-900 dark:bg-brand-yellow text-white dark:text-zinc-950 rounded-lg text-xs font-bold hover:opacity-90 transition-colors"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -100,9 +100,6 @@ export const SuperAdmin: React.FC = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await impersonateTenant(tenantId);
|
await impersonateTenant(tenantId);
|
||||||
// Force a full reload to clear any cached context/state in the React app
|
|
||||||
window.location.hash = '#/';
|
|
||||||
window.location.reload();
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
alert(err.message || 'Erro ao tentar entrar na organização.');
|
alert(err.message || 'Erro ao tentar entrar na organização.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -357,7 +357,11 @@ export const deleteTenant = async (id: string): Promise<boolean> => {
|
|||||||
|
|
||||||
// --- Auth Functions ---
|
// --- Auth Functions ---
|
||||||
|
|
||||||
|
// Flag to prevent background fetches from throwing 401 and logging out during impersonation handoffs
|
||||||
|
export let isReloadingForImpersonation = false;
|
||||||
|
|
||||||
export const logout = () => {
|
export const logout = () => {
|
||||||
|
if (isReloadingForImpersonation) return; // Prevent logout if we are just switching tokens
|
||||||
localStorage.removeItem('ctms_token');
|
localStorage.removeItem('ctms_token');
|
||||||
localStorage.removeItem('ctms_user_id');
|
localStorage.removeItem('ctms_user_id');
|
||||||
localStorage.removeItem('ctms_tenant_id');
|
localStorage.removeItem('ctms_tenant_id');
|
||||||
@@ -401,6 +405,8 @@ export const impersonateTenant = async (tenantId: string): Promise<any> => {
|
|||||||
throw new Error(errorData.error || 'Erro ao assumir identidade');
|
throw new Error(errorData.error || 'Erro ao assumir identidade');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isReloadingForImpersonation = true; // Block logouts
|
||||||
|
|
||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
const oldToken = localStorage.getItem('ctms_token');
|
const oldToken = localStorage.getItem('ctms_token');
|
||||||
if (oldToken) {
|
if (oldToken) {
|
||||||
@@ -410,6 +416,10 @@ export const impersonateTenant = async (tenantId: string): Promise<any> => {
|
|||||||
localStorage.setItem('ctms_token', data.token);
|
localStorage.setItem('ctms_token', data.token);
|
||||||
localStorage.setItem('ctms_user_id', data.user.id);
|
localStorage.setItem('ctms_user_id', data.user.id);
|
||||||
localStorage.setItem('ctms_tenant_id', data.user.tenant_id || '');
|
localStorage.setItem('ctms_tenant_id', data.user.tenant_id || '');
|
||||||
|
|
||||||
|
window.location.hash = '#/';
|
||||||
|
window.location.reload();
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -417,13 +427,31 @@ export const returnToSuperAdmin = (): boolean => {
|
|||||||
const superAdminToken = localStorage.getItem('ctms_super_admin_token');
|
const superAdminToken = localStorage.getItem('ctms_super_admin_token');
|
||||||
if (superAdminToken) {
|
if (superAdminToken) {
|
||||||
try {
|
try {
|
||||||
const payload = JSON.parse(atob(superAdminToken.split('.')[1]));
|
isReloadingForImpersonation = true; // Block logouts
|
||||||
|
|
||||||
|
// Correctly decode Base64Url JWT payload with proper padding
|
||||||
|
const base64Url = superAdminToken.split('.')[1];
|
||||||
|
let base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
||||||
|
const pad = base64.length % 4;
|
||||||
|
if (pad) {
|
||||||
|
base64 += '='.repeat(4 - pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
const jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
|
||||||
|
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||||
|
}).join(''));
|
||||||
|
const payload = JSON.parse(jsonPayload);
|
||||||
|
|
||||||
localStorage.setItem('ctms_token', superAdminToken);
|
localStorage.setItem('ctms_token', superAdminToken);
|
||||||
localStorage.setItem('ctms_user_id', payload.id);
|
localStorage.setItem('ctms_user_id', payload.id);
|
||||||
localStorage.setItem('ctms_tenant_id', payload.tenant_id || 'system');
|
localStorage.setItem('ctms_tenant_id', payload.tenant_id || 'system');
|
||||||
localStorage.removeItem('ctms_super_admin_token');
|
localStorage.removeItem('ctms_super_admin_token');
|
||||||
|
|
||||||
|
window.location.hash = '#/super-admin';
|
||||||
|
window.location.reload();
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
isReloadingForImpersonation = false;
|
||||||
console.error("Failed to restore super admin token", e);
|
console.error("Failed to restore super admin token", e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user