diff --git a/frontend/src/authProvider.ts b/frontend/src/authProvider.ts new file mode 100644 index 0000000..474140b --- /dev/null +++ b/frontend/src/authProvider.ts @@ -0,0 +1,60 @@ +import Keycloak from 'keycloak-js'; +import { AuthProvider } from 'react-admin'; + +const keycloak = new Keycloak({ + url: 'https://sso.greact.ru', + realm: 'toir-light-v4', + clientId: 'toir-light-v4-frontend', +}); + +let authenticated = false; + +export const initKeycloak = async (): Promise => { + authenticated = await keycloak.init({ + onLoad: 'login-required', + checkLoginIframe: false, + }); + return authenticated; +}; + +export const getToken = (): string | undefined => keycloak.token; + +export const authProvider: AuthProvider = { + login: async () => { + if (!authenticated) { + await keycloak.login(); + } + }, + logout: async () => { + await keycloak.logout({ redirectUri: window.location.origin }); + }, + checkError: async (error) => { + if (error.status === 401 || error.status === 403) { + try { + const refreshed = await keycloak.updateToken(30); + if (!refreshed) throw new Error('Token refresh failed'); + } catch { + await keycloak.logout({ redirectUri: window.location.origin }); + throw new Error('Session expired'); + } + } + }, + checkAuth: async () => { + if (!keycloak.authenticated) { + throw new Error('Not authenticated'); + } + try { + await keycloak.updateToken(30); + } catch { + throw new Error('Token refresh failed'); + } + }, + getPermissions: async () => { + const roles = keycloak.tokenParsed?.realm_access?.roles ?? []; + return roles; + }, + getIdentity: async () => ({ + id: keycloak.tokenParsed?.sub ?? '', + fullName: keycloak.tokenParsed?.preferred_username ?? '', + }), +};