@oondemand/oon-core-front 0.7.4 → 0.7.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{chunk-TTQQMP5K.js → chunk-3JBDEAKP.js} +12 -6
- package/dist/chunk-3JBDEAKP.js.map +1 -0
- package/dist/{chunk-7FZ32EWV.js → chunk-5P3N4KJX.js} +3 -3
- package/dist/{chunk-DNQQRKHM.js → chunk-7XXROGIF.js} +96 -32
- package/dist/chunk-7XXROGIF.js.map +1 -0
- package/dist/{chunk-A6FWKKZA.js → chunk-JXU6W3ZU.js} +13 -7
- package/dist/chunk-JXU6W3ZU.js.map +1 -0
- package/dist/{hooks-lXMaiLqz.d.ts → hooks-CUJuAfh1.d.ts} +1 -0
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -4
- package/dist/testing.js +3 -3
- package/dist/ui.js +3 -3
- package/package.json +1 -1
- package/dist/chunk-A6FWKKZA.js.map +0 -1
- package/dist/chunk-DNQQRKHM.js.map +0 -1
- package/dist/chunk-TTQQMP5K.js.map +0 -1
- /package/dist/{chunk-7FZ32EWV.js.map → chunk-5P3N4KJX.js.map} +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# OonCore Front - ativação de instâncias
|
|
2
2
|
|
|
3
|
+
Para criar ou alterar um App, comece pela entrada curta distribuída pelo gerador em `.ooncore/AGENTS.md` e pelo índice `.ooncore/docs/TASK_INDEX.md`. Bootstrap, rotas privadas, permissões, prefixos, erros e `sensitiveBody` estão consolidados em `.ooncore/docs/PUBLIC_CONTRACTS.md`. Esta referência detalhada é para consulta sob demanda.
|
|
4
|
+
|
|
3
5
|
## Runtime local desconectado
|
|
4
6
|
|
|
5
7
|
`runtimeMode: "local"` troca o bootstrap de uso único por cookie HttpOnly, usa CSRF nas mutações, não persiste bearer no `localStorage`, reconhece `ativa_local` e exibe o banner de desenvolvimento desconectado com expiração e seleção dos perfis declarados no manifesto.
|
|
@@ -135,7 +135,7 @@ function createRestClient(deps) {
|
|
|
135
135
|
(error) => {
|
|
136
136
|
const normalized = normalizeError(error);
|
|
137
137
|
const requestPath = String(error.config?.url || "").split("?")[0].replace(/\/$/, "");
|
|
138
|
-
const isLogin = requestPath.endsWith("/auth/autenticar");
|
|
138
|
+
const isLogin = requestPath.endsWith("/auth/autenticar") || /\/core\/invitations\/(?:accept|inspect|[^/]+\/accept)$/.test(requestPath);
|
|
139
139
|
if (normalized.status === 401 && !isLogin && !error.config?.signal?.aborted) onUnauthorized?.();
|
|
140
140
|
return Promise.reject(normalized);
|
|
141
141
|
}
|
|
@@ -476,7 +476,7 @@ function AuthProvider({ http, storage, auth, loginUrl, runtimeMode = "platform",
|
|
|
476
476
|
const launchAbort = useRef2(null);
|
|
477
477
|
const launchSession = useRef2(null);
|
|
478
478
|
const redirectToExternalLogin = useCallback3(() => {
|
|
479
|
-
if (runtimeMode === "local") return;
|
|
479
|
+
if (runtimeMode === "local" || window.location.pathname === "/accept-invite") return;
|
|
480
480
|
if (loginUrl) window.location.href = loginUrl;
|
|
481
481
|
}, [loginUrl, runtimeMode]);
|
|
482
482
|
const applyUser = useCallback3((next) => {
|
|
@@ -569,7 +569,7 @@ function AuthProvider({ http, storage, auth, loginUrl, runtimeMode = "platform",
|
|
|
569
569
|
await http.post("/auth/first-access/password", { password });
|
|
570
570
|
await validateSession();
|
|
571
571
|
}, [http, validateSession]);
|
|
572
|
-
const logout = useCallback3(() => {
|
|
572
|
+
const logout = useCallback3((options) => {
|
|
573
573
|
launchAbort.current?.abort();
|
|
574
574
|
launchSession.current = null;
|
|
575
575
|
storage.clear();
|
|
@@ -580,7 +580,7 @@ function AuthProvider({ http, storage, auth, loginUrl, runtimeMode = "platform",
|
|
|
580
580
|
void http.post("/auth/local/logout").catch(() => void 0);
|
|
581
581
|
return;
|
|
582
582
|
}
|
|
583
|
-
redirectToExternalLogin();
|
|
583
|
+
if (options?.redirect !== false) redirectToExternalLogin();
|
|
584
584
|
}, [storage, redirectToExternalLogin, clearTenant, runtimeMode, http]);
|
|
585
585
|
useEffect2(() => {
|
|
586
586
|
let active = true;
|
|
@@ -605,6 +605,11 @@ function AuthProvider({ http, storage, auth, loginUrl, runtimeMode = "platform",
|
|
|
605
605
|
active = false;
|
|
606
606
|
};
|
|
607
607
|
}
|
|
608
|
+
if (window.location.pathname === "/accept-invite") {
|
|
609
|
+
setUser(null);
|
|
610
|
+
setStatus("unauthenticated");
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
608
613
|
const launchCode = captureTokenFromUrl("oon_launch");
|
|
609
614
|
const incoming = captureTokenFromUrl(tokenParam);
|
|
610
615
|
const stored = storage.get();
|
|
@@ -694,7 +699,8 @@ function AuthProvider({ http, storage, auth, loginUrl, runtimeMode = "platform",
|
|
|
694
699
|
login,
|
|
695
700
|
completeFirstAccess,
|
|
696
701
|
retry,
|
|
697
|
-
logout
|
|
702
|
+
logout: () => logout(),
|
|
703
|
+
clearSession: () => logout({ redirect: false })
|
|
698
704
|
};
|
|
699
705
|
return /* @__PURE__ */ jsx4(AuthContext.Provider, { value, children });
|
|
700
706
|
}
|
|
@@ -720,4 +726,4 @@ export {
|
|
|
720
726
|
AuthProvider,
|
|
721
727
|
useOonAuth
|
|
722
728
|
};
|
|
723
|
-
//# sourceMappingURL=chunk-
|
|
729
|
+
//# sourceMappingURL=chunk-3JBDEAKP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/api/ApiProvider.tsx","../src/api/coreClient.ts","../src/api/createRestClient.ts","../src/api/errorNormalizer.ts","../src/api/resourceClient.ts","../src/security/TenantProvider.tsx","../src/security/AuthProvider.tsx","../src/security/tokenStorage.ts","../src/security/ActivationProvider.tsx"],"sourcesContent":["import { createContext, useContext, useMemo, type ReactNode } from \"react\";\nimport type { AxiosInstance } from \"axios\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport type { ModelSummary } from \"../types\";\nimport { createCoreClient, type CoreClient } from \"./coreClient\";\nimport { createResourceClient, type ResourceClient } from \"./resourceClient\";\n\ninterface ApiContextValue {\n http: AxiosInstance;\n core: CoreClient;\n resource: <T = Record<string, unknown>>(basePath: string) => ResourceClient<T>;\n}\n\nconst ApiContext = createContext<ApiContextValue | null>(null);\n\nexport function ApiProvider({ http, children }: { http: AxiosInstance; children: ReactNode }) {\n const value = useMemo<ApiContextValue>(() => {\n const cache = new Map<string, ResourceClient>();\n return {\n http,\n core: createCoreClient(http),\n resource<T = Record<string, unknown>>(basePath: string) {\n let client = cache.get(basePath);\n if (!client) {\n client = createResourceClient(http, basePath);\n cache.set(basePath, client);\n }\n return client as ResourceClient<T>;\n },\n };\n }, [http]);\n\n return <ApiContext.Provider value={value}>{children}</ApiContext.Provider>;\n}\n\nexport function useOonApi(): ApiContextValue {\n const ctx = useContext(ApiContext);\n if (!ctx) throw new Error(\"useOonApi deve ser usado dentro de <ApiProvider> (oonCoreFront.start).\");\n return ctx;\n}\n\n/** Cliente de um recurso, memoizado pelo basePath. */\nexport function useOonResource<T = Record<string, unknown>>(basePath: string): ResourceClient<T> {\n const { resource } = useOonApi();\n return useMemo(() => resource<T>(basePath), [resource, basePath]);\n}\n\n/** Metadata completa do back (cache de 5 min). */\nexport function useCoreMetadata() {\n const { core } = useOonApi();\n return useQuery({\n queryKey: [\"oon\", \"core\", \"metadata\"],\n queryFn: () => core.metadata(),\n staleTime: 5 * 60 * 1000,\n });\n}\n\n/** Descrição de uma model específica — base do modo \"dynamic\". */\nexport function useModelSchema(name: string, enabled = true) {\n const { core } = useOonApi();\n return useQuery<ModelSummary>({\n queryKey: [\"oon\", \"core\", \"model\", name],\n queryFn: () => core.model(name),\n staleTime: 5 * 60 * 1000,\n enabled: enabled && !!name,\n });\n}\n","import type { AxiosInstance } from \"axios\";\nimport type { CoreMetadata, ModelSummary } from \"../types\";\n\n/**\n * SDK do contrato /core/* (introspecção dirigida por metadata). É o que\n * permite o modo \"dynamic\" das coleções: o front monta grid/form/rotas a\n * partir do que o back descreve, sem código de UI por entidade.\n */\nexport interface CoreClient {\n metadata(): Promise<CoreMetadata>;\n models(): Promise<ModelSummary[]>;\n model(name: string): Promise<ModelSummary>;\n permissions(): Promise<Array<{ resource: string; action: string; roles: string[] }>>;\n menus(): Promise<CoreMetadata[\"menus\"]>;\n}\n\nexport function createCoreClient(http: AxiosInstance): CoreClient {\n return {\n async metadata() {\n const { data } = await http.get<CoreMetadata>(\"/core/metadata\");\n return data;\n },\n async models() {\n const { data } = await http.get<{ results: ModelSummary[] }>(\"/core/models\");\n return data.results;\n },\n async model(name) {\n const { data } = await http.get<ModelSummary>(`/core/models/${name}`);\n return data;\n },\n async permissions() {\n const { data } = await http.get<{ results: Array<{ resource: string; action: string; roles: string[] }> }>(\n \"/core/permissions\"\n );\n return data.results;\n },\n async menus() {\n const { data } = await http.get<{ results: CoreMetadata[\"menus\"] }>(\"/core/menus\");\n return data.results;\n },\n };\n}\n","import axios, { type AxiosInstance } from \"axios\";\nimport type { AuditContext, OonApiConfig, OonRuntimeMode } from \"../types\";\nimport { normalizeError } from \"./errorNormalizer\";\n\nexport interface RestClientDeps {\n api: OonApiConfig;\n /** Lê o token atual (Bearer). Retorna null se não autenticado. */\n getToken: () => string | null;\n /** Lê a seleção atual de tenant. O backend continua sendo a autoridade. */\n getTenantId?: () => string | null;\n /** Chamado uma vez ao receber 401 (logout + redirect). */\n onUnauthorized?: () => void;\n /** Origem app id, vai no header x-oon-app. */\n appId?: string;\n runtimeMode?: OonRuntimeMode;\n}\n\nfunction readCookie(name: string): string | null {\n try {\n const prefix = `${name}=`;\n const value = document.cookie\n .split(\";\")\n .map((item) => item.trim())\n .find((item) => item.startsWith(prefix));\n return value ? decodeURIComponent(value.slice(prefix.length)) : null;\n } catch {\n return null;\n }\n}\n\n/**\n * Cliente REST único do Core (Seção 2.5). Centraliza:\n * - baseUrl + versionPrefix;\n * - injeção de Bearer token;\n * - seleção de tenant via x-oon-tenant-id;\n * - headers de auditoria x-oon-* nas mutações;\n * - tratamento global de 401 e normalização de erro.\n */\nexport function createRestClient(deps: RestClientDeps): AxiosInstance {\n const { api, getToken, getTenantId, onUnauthorized, appId, runtimeMode = \"platform\" } = deps;\n const prefix = api.versionPrefix ?? \"\";\n\n const instance = axios.create({\n baseURL: `${api.baseUrl.replace(/\\/$/, \"\")}${prefix}`,\n timeout: api.timeout ?? 30000,\n withCredentials: runtimeMode === \"local\",\n });\n\n instance.interceptors.request.use((config) => {\n const token = runtimeMode === \"local\" ? null : getToken();\n if (token && config.headers.Authorization !== false && !config.headers.Authorization) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n // A chamada pode selecionar um tenant específico mesmo quando o shell está\n // em modo global multi-tenant. Nesse caso, o header explícito tem precedência\n // sobre a seleção global e nunca deve ser removido pelo interceptor.\n const explicitTenantId = config.headers.get(\"x-oon-tenant-id\");\n // Axios usa false para suprimir um header nesta requisição. O handshake\n // de launch não pode herdar seleção de storage/defaults de outra sessão.\n const tenantId = explicitTenantId === false ? null : explicitTenantId || getTenantId?.();\n if (tenantId) config.headers.set(\"x-oon-tenant-id\", String(tenantId));\n else config.headers.delete(\"x-oon-tenant-id\");\n if (appId) config.headers[\"x-oon-app\"] = appId;\n if (\n runtimeMode === \"local\"\n && ![\"get\", \"head\", \"options\"].includes(String(config.method || \"get\").toLowerCase())\n ) {\n const csrf = readCookie(\"oon_local_csrf\");\n if (csrf) config.headers.set(\"x-oon-local-csrf\", csrf);\n }\n return config;\n });\n\n instance.interceptors.response.use(\n (res) => res,\n (error) => {\n const normalized = normalizeError(error);\n const requestPath = String(error.config?.url || \"\")\n .split(\"?\")[0]\n .replace(/\\/$/, \"\");\n const isLogin = requestPath.endsWith(\"/auth/autenticar\") || /\\/core\\/invitations\\/(?:accept|inspect|[^/]+\\/accept)$/.test(requestPath);\n if (normalized.status === 401 && !isLogin && !error.config?.signal?.aborted) onUnauthorized?.();\n return Promise.reject(normalized);\n }\n );\n\n return instance;\n}\n\n/** Monta os headers de auditoria x-oon-* a partir do contexto. */\nexport function auditHeaders(audit?: AuditContext): Record<string, string> {\n if (!audit) return {};\n const headers: Record<string, string> = {};\n if (audit.origem) headers[\"x-oon-origin\"] = audit.origem;\n if (audit.module) headers[\"x-oon-module\"] = audit.module;\n if (audit.entity) headers[\"x-oon-entity\"] = audit.entity;\n return headers;\n}\n\n\n","import axios from \"axios\";\nimport type { OonError } from \"../types\";\n\ntype ErrorEnvelope = {\n code?: string;\n message?: string;\n details?: unknown;\n requestId?: string;\n field?: string;\n technicalMessage?: string;\n [key: string]: unknown;\n};\n\ntype ErrorPayload = {\n code?: string;\n message?: string;\n details?: unknown;\n requestId?: string;\n error?: ErrorEnvelope | string;\n};\n\n/**\n * Normaliza qualquer erro de rede/axios para o formato `OonError`, lendo o\n * envelope de erro padrão do back (`{ message }` ou `{ error: {...} }`).\n */\nexport function normalizeError(err: unknown): OonError {\n if (axios.isAxiosError(err)) {\n const status = err.response?.status;\n const data = err.response?.data as string | ErrorPayload | undefined;\n const responseRequestId = (\n err.response?.headers?.[\"x-request-id\"]\n ?? err.response?.headers?.[\"x-correlation-id\"]\n ) as string | undefined;\n\n const contentType = String(err.response?.headers?.[\"content-type\"] || \"\");\n const isTextPayload = typeof data === \"string\";\n const isProbablyHtml = isTextPayload && /<html|<!doctype/i.test(data);\n\n if (isTextPayload || (contentType && !contentType.includes(\"json\"))) {\n return {\n code: codeFromStatus(status),\n message: nonJsonMessage(status, err.config?.url, isProbablyHtml),\n status,\n details: isProbablyHtml ? undefined : data,\n requestId: responseRequestId,\n };\n }\n\n const rawError = data?.error;\n const envelope = rawError && typeof rawError === \"object\" ? rawError : undefined;\n const legacyDetails = envelope && envelope.details === undefined && envelope.field\n ? envelope\n : undefined;\n const rawTechnicalDetails = typeof rawError === \"string\"\n ? { technicalMessage: rawError }\n : undefined;\n\n return {\n code: envelope?.code || data?.code || codeFromStatus(status),\n message: envelope?.message || data?.message || err.message || \"Erro inesperado.\",\n status,\n details: envelope?.details ?? legacyDetails ?? data?.details ?? rawTechnicalDetails,\n requestId: envelope?.requestId || data?.requestId || responseRequestId,\n };\n }\n\n if (err instanceof Error) {\n return { code: \"UNKNOWN\", message: err.message };\n }\n\n return { code: \"UNKNOWN\", message: \"Erro inesperado.\" };\n}\n\nfunction nonJsonMessage(status?: number, url?: string, html?: boolean): string {\n const path = url ? ` (${url})` : \"\";\n if (status === 404) {\n return `Rota da API não encontrada${path}. Verifique VITE_API_URL, porta do backend e modo da Central.`;\n }\n if (html) {\n return `Backend retornou HTML em vez de JSON${path}. Verifique se o frontend está apontando para a API correta.`;\n }\n return `Backend retornou resposta não JSON${path}. Verifique a configuração da API.`;\n}\n\nfunction codeFromStatus(status?: number): string {\n switch (status) {\n case 400:\n return \"VALIDATION_ERROR\";\n case 401:\n return \"UNAUTHORIZED\";\n case 403:\n return \"FORBIDDEN\";\n case 404:\n return \"NOT_FOUND\";\n case 409:\n return \"CONFLICT\";\n default:\n return status && status >= 500 ? \"SERVER_ERROR\" : \"REQUEST_ERROR\";\n }\n}\n","import type { AxiosInstance } from \"axios\";\nimport type { AuditContext, ListParams, PaginatedResult } from \"../types\";\nimport { auditHeaders } from \"./createRestClient\";\n\n/**\n * SDK por recurso (Seção 2.5). Espelha o CRUD gerado pelo back em `basePath`:\n * GET / -> list (paginado)\n * GET /:id -> get\n * POST / -> create\n * PUT /:id -> update\n * PATCH /:id -> patch\n * DELETE /:id -> delete\n * POST /import -> importMany\n * GET /export -> exportAll\n *\n * O back devolve registro único na chave do singular (`{ [singular]: {...} }`);\n * `unwrap` extrai o primeiro valor não-meta para o consumidor não precisar\n * conhecer o singular.\n */\nexport interface ResourceClient<T = Record<string, unknown>> {\n list(params?: ListParams): Promise<PaginatedResult<T>>;\n get(id: string): Promise<T>;\n create(body: Partial<T>, audit?: AuditContext): Promise<T>;\n update(id: string, body: Partial<T>, audit?: AuditContext): Promise<T>;\n patch(id: string, body: Partial<T>, audit?: AuditContext): Promise<T>;\n delete(id: string, audit?: AuditContext): Promise<T>;\n importMany(rows: unknown[], audit?: AuditContext): Promise<{ inserted?: number; [k: string]: unknown }>;\n exportAll(params?: ListParams): Promise<T[]>;\n}\n\nconst META_KEYS = new Set([\"pagination\", \"results\", \"message\", \"requestId\"]);\n\nfunction unwrap<T>(data: Record<string, unknown>): T {\n // resposta tipo { pessoa: {...} } — pega o primeiro valor de objeto.\n for (const [key, value] of Object.entries(data)) {\n if (!META_KEYS.has(key) && value && typeof value === \"object\") {\n return value as T;\n }\n }\n return data as T;\n}\n\nexport function createResourceClient<T = Record<string, unknown>>(\n http: AxiosInstance,\n basePath: string\n): ResourceClient<T> {\n const base = `/${basePath.replace(/^\\/+/, \"\")}`;\n\n return {\n async list(params) {\n const { data } = await http.get<PaginatedResult<T>>(base, { params });\n return data;\n },\n async get(id) {\n const { data } = await http.get<Record<string, unknown>>(`${base}/${id}`);\n return unwrap<T>(data);\n },\n async create(body, audit) {\n const { data } = await http.post<Record<string, unknown>>(base, body, {\n headers: auditHeaders(audit ?? { origem: \"form\" }),\n });\n return unwrap<T>(data);\n },\n async update(id, body, audit) {\n const { data } = await http.put<Record<string, unknown>>(`${base}/${id}`, body, {\n headers: auditHeaders(audit ?? { origem: \"form\" }),\n });\n return unwrap<T>(data);\n },\n async patch(id, body, audit) {\n const { data } = await http.patch<Record<string, unknown>>(`${base}/${id}`, body, {\n headers: auditHeaders(audit ?? { origem: \"datagrid\" }),\n });\n return unwrap<T>(data);\n },\n async delete(id, audit) {\n const { data } = await http.delete<Record<string, unknown>>(`${base}/${id}`, {\n headers: auditHeaders(audit ?? { origem: \"datagrid\" }),\n });\n return unwrap<T>(data);\n },\n async importMany(rows, audit) {\n const { data } = await http.post<{ inserted?: number }>(\n `${base}/import`,\n { rows },\n { headers: auditHeaders(audit ?? { origem: \"import\" }) }\n );\n return data;\n },\n async exportAll(params) {\n const { data } = await http.get<{ results: T[] } | T[]>(`${base}/export`, { params });\n return Array.isArray(data) ? data : data.results;\n },\n };\n}\n","import {\n createContext,\n type ReactNode,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport type { AxiosInstance } from \"axios\";\nimport type { TenantStorage } from \"./tenantStorage\";\n\nexport interface OonTenantContextValue {\n activeTenantId: string | null;\n switchTenant(tenantId: string): void;\n clearTenant(): void;\n}\n\nconst TenantContext = createContext<OonTenantContextValue | null>(null);\n\nexport interface TenantProviderProps {\n http: AxiosInstance;\n storage: TenantStorage;\n children: ReactNode;\n}\n\nfunction applyHeader(http: AxiosInstance, tenantId: string | null) {\n if (tenantId) {\n http.defaults.headers.common[\"x-oon-tenant-id\"] = tenantId;\n return;\n }\n delete http.defaults.headers.common[\"x-oon-tenant-id\"];\n}\n\n/**\n * Gerencia somente a seleção ativa. O backend continua sendo a autoridade e\n * precisa validar o tenant antes de materializar req.accessContext.\n */\nexport function TenantProvider({ http, storage, children }: TenantProviderProps) {\n const queryClient = useQueryClient();\n const [activeTenantId, setActiveTenantId] = useState<string | null>(() => storage.get());\n const selectedTenant = useRef(activeTenantId);\n\n const replaceTenant = useCallback(\n (tenantId: string | null) => {\n const normalized = String(tenantId ?? \"\").trim() || null;\n if (normalized) storage.set(normalized);\n else storage.clear();\n applyHeader(http, normalized);\n setActiveTenantId(normalized);\n\n // Nunca reutilizar cache entre tenants. `clear()` remove queries inativas,\n // dados observados e mutations pendentes do contexto anterior.\n if (selectedTenant.current !== normalized) {\n selectedTenant.current = normalized;\n queryClient.clear();\n }\n },\n [http, queryClient, storage],\n );\n\n const switchTenant = useCallback((tenantId: string) => {\n if (!tenantId?.trim()) throw new Error(\"tenantId é obrigatório.\");\n replaceTenant(tenantId);\n }, [replaceTenant]);\n const clearTenant = useCallback(() => replaceTenant(null), [replaceTenant]);\n\n const value = useMemo<OonTenantContextValue>(\n () => ({ activeTenantId, switchTenant, clearTenant }),\n [activeTenantId, switchTenant, clearTenant],\n );\n\n return <TenantContext.Provider value={value}>{children}</TenantContext.Provider>;\n}\n\nexport function useOptionalOonTenant(): OonTenantContextValue | null {\n return useContext(TenantContext);\n}\n\nexport function useOonTenant(): OonTenantContextValue {\n const value = useOptionalOonTenant();\n if (!value) throw new Error(\"useOonTenant deve ser usado dentro de TenantProvider.\");\n return value;\n}\n\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport type { AxiosInstance } from \"axios\";\nimport type { OonAuthConfig, OonError, OonUser } from \"../types\";\nimport { captureTokenFromUrl, type TokenStorage } from \"./tokenStorage\";\nimport { useOptionalActivation } from \"./ActivationProvider\";\nimport { useOptionalOonTenant } from \"./TenantProvider\";\n\nexport type AuthStatus =\n | \"loading\"\n | \"authenticated\"\n | \"first-access\"\n | \"unauthenticated\"\n | \"forbidden\"\n | \"error\";\n\ninterface AuthContextValue {\n user: OonUser | null;\n roles: string[];\n capabilities: string[];\n permissions: string[];\n status: AuthStatus;\n isAuthenticated: boolean;\n hasPermission: (permission?: string | string[]) => boolean;\n login: (email: string, password: string, tenantId?: string) => Promise<void>;\n completeFirstAccess: (password: string) => Promise<void>;\n retry: () => Promise<void>;\n logout: () => void;\n clearSession: () => void;\n}\n\nconst AuthContext = createContext<AuthContextValue | null>(null);\n\nexport interface AuthProviderProps {\n http: AxiosInstance;\n storage: TokenStorage;\n auth?: OonAuthConfig;\n loginUrl?: string;\n runtimeMode?: \"platform\" | \"local\";\n children: ReactNode;\n}\n\nfunction errorStatus(error: unknown): number | undefined {\n return (error as OonError | undefined)?.status;\n}\n\nfunction encodeBasicCredentials(email: string, password: string): string {\n const bytes = new TextEncoder().encode(`${email}:${password}`);\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return window.btoa(binary);\n}\n\nfunction normalizeList(value: unknown): string[] {\n if (Array.isArray(value)) return value.map(String).filter(Boolean);\n if (typeof value === \"string\") return value.split(/[\\s,;]+/).map((item) => item.trim()).filter(Boolean);\n return [];\n}\n\nfunction unique(values: string[]): string[] {\n return values.filter((item, index, all) => Boolean(item) && all.indexOf(item) === index);\n}\n\nfunction extractCapabilities(user: OonUser | null): string[] {\n if (!user) return [];\n return unique([\n ...normalizeList(user.capabilities),\n ...normalizeList(user.permissoes?.capabilities),\n ...normalizeList(user.aplicativo?.capabilities),\n ...normalizeList(user.aplicativo?.permissoes?.capabilities),\n ]);\n}\n\nfunction explicitPermissions(user: OonUser | null): string[] | null {\n if (!user) return [];\n const value = (user as OonUser & { permissions?: string[] }).permissions;\n return Array.isArray(value) ? unique(value.map(String)) : null;\n}\n\nexport function can(\n user: OonUser | null,\n permission?: string | string[],\n): boolean {\n if (!permission) return true;\n const required = Array.isArray(permission) ? permission : [permission];\n if (!required.length) return true;\n\n const canonical = explicitPermissions(user);\n if (canonical) {\n return canonical.includes(\"*\") || required.some((value) => canonical.includes(value));\n }\n\n // Compatibilidade com backends anteriores ao RBAC canônico.\n const roles = unique(normalizeList((user as OonUser & { roleCode?: string })?.roleCode).concat(normalizeList(user?.tipo)));\n const capabilities = extractCapabilities(user);\n if (roles.includes(\"admin\") || roles.includes(\"master\")) return true;\n return required.some((value) => roles.includes(value) || capabilities.includes(value));\n}\n\nexport function AuthProvider({ http, storage, auth, loginUrl, runtimeMode = \"platform\", children }: AuthProviderProps) {\n const tokenParam = auth?.tokenParam ?? \"code\";\n const devToken = auth?.devToken?.trim() || null;\n const [user, setUser] = useState<OonUser | null>(null);\n const [status, setStatus] = useState<AuthStatus>(\"loading\");\n const activation = useOptionalActivation();\n const tenantContext = useOptionalOonTenant();\n const switchTenant = tenantContext?.switchTenant;\n const clearTenant = tenantContext?.clearTenant;\n // Compartilha o handshake entre reexecuções de effects (inclusive StrictMode).\n const launchAbort = useRef<AbortController | null>(null);\n const launchSession = useRef<Promise<{ token: string; user: OonUser }> | null>(null);\n\n const redirectToExternalLogin = useCallback(() => {\n if (runtimeMode === \"local\" || window.location.pathname === \"/accept-invite\") return;\n if (loginUrl) window.location.href = loginUrl;\n }, [loginUrl, runtimeMode]);\n\n const applyUser = useCallback((next: OonUser) => {\n setUser(next);\n const tenant = next.tenant as { id?: string } | undefined;\n const resolvedTenantId = String(next.tenantId || tenant?.id || \"\").trim();\n if (resolvedTenantId) switchTenant?.(resolvedTenantId);\n const firstAccess = Boolean(\n (next as OonUser & { mustChangePassword?: boolean; firstAccessPending?: boolean }).mustChangePassword ||\n (next as OonUser & { firstAccessPending?: boolean }).firstAccessPending,\n );\n setStatus(firstAccess ? \"first-access\" : \"authenticated\");\n }, [switchTenant]);\n\n const applyValidationError = useCallback(\n (error: unknown) => {\n const currentStatus = errorStatus(error);\n setUser(null);\n if (currentStatus === 403) {\n setStatus(\"forbidden\");\n return;\n }\n if (currentStatus === 401) {\n storage.clear();\n setStatus(\"unauthenticated\");\n redirectToExternalLogin();\n return;\n }\n setStatus(\"error\");\n },\n [storage, redirectToExternalLogin],\n );\n\n const validateSession = useCallback(async () => {\n const response = await http.get<{ usuario: OonUser }>(\"/auth/validar-token\");\n applyUser(response.data.usuario);\n }, [http, applyUser]);\n\n const retry = useCallback(async () => {\n setStatus(\"loading\");\n try {\n await validateSession();\n } catch (error) {\n applyValidationError(error);\n throw error;\n }\n }, [validateSession, applyValidationError]);\n\n const login = useCallback(\n async (email: string, password: string, tenantId?: string) => {\n if (runtimeMode === \"local\") {\n const error: OonError = {\n code: \"LOCAL_LOGIN_NOT_SUPPORTED\",\n message: \"O runtime local não utiliza conta da plataforma.\",\n status: 403,\n };\n throw error;\n }\n launchAbort.current?.abort();\n launchSession.current = null;\n setStatus(\"loading\");\n setUser(null);\n try {\n const normalizedTenantId = String(tenantId || \"\").trim();\n if (normalizedTenantId) switchTenant?.(normalizedTenantId);\n else clearTenant?.();\n const response = await http.post<{ token: string }>(\n \"/auth/autenticar\",\n {},\n {\n headers: {\n Authorization: `Basic ${encodeBasicCredentials(email, password)}`,\n ...(normalizedTenantId ? { \"x-oon-tenant-id\": normalizedTenantId } : {}),\n },\n },\n );\n if (!response.data.token) {\n const error: OonError = { code: \"AUTH_TOKEN_MISSING\", message: \"Token não retornado pelo backend.\", status: 502 };\n throw error;\n }\n storage.set(response.data.token);\n await validateSession();\n } catch (error) {\n if ((error as OonError | undefined)?.code === \"TENANT_SELECTION_REQUIRED\") {\n setStatus(\"unauthenticated\");\n } else {\n applyValidationError(error);\n }\n throw error;\n }\n },\n [http, storage, validateSession, applyValidationError, switchTenant, clearTenant, runtimeMode],\n );\n\n const completeFirstAccess = useCallback(async (password: string) => {\n await http.post(\"/auth/first-access/password\", { password });\n await validateSession();\n }, [http, validateSession]);\n\n const logout = useCallback((options?: { redirect?: boolean }) => {\n launchAbort.current?.abort();\n launchSession.current = null;\n storage.clear();\n clearTenant?.();\n setUser(null);\n setStatus(\"unauthenticated\");\n if (runtimeMode === \"local\") {\n void http.post(\"/auth/local/logout\").catch(() => undefined);\n return;\n }\n if (options?.redirect !== false) redirectToExternalLogin();\n }, [storage, redirectToExternalLogin, clearTenant, runtimeMode, http]);\n\n useEffect(() => {\n let active = true;\n if (activation && ![\"active\", \"error\"].includes(activation.status)) {\n setUser(null);\n setStatus(\"unauthenticated\");\n return;\n }\n if (runtimeMode === \"local\") {\n storage.clear();\n const bootstrapCode = captureTokenFromUrl(\"oon_local_bootstrap\");\n setStatus(\"loading\");\n const bootstrap = bootstrapCode\n ? http.post(\"/auth/local/bootstrap\", { code: bootstrapCode })\n : Promise.resolve();\n bootstrap\n .then(() => http.get<{ usuario: OonUser }>(\"/auth/validar-token\"))\n .then((response) => {\n if (!active) return;\n applyUser(response.data.usuario);\n })\n .catch((error) => {\n if (!active) return;\n applyValidationError(error);\n });\n return () => { active = false; };\n }\n // Invitation inspection validates identity without requiring its pending grant.\n // Keep the stored credential for that request; protected routes still validate\n // normally when the app is reloaded after acceptance.\n if (window.location.pathname === \"/accept-invite\") {\n setUser(null);\n setStatus(\"unauthenticated\");\n return;\n }\n const launchCode = captureTokenFromUrl(\"oon_launch\");\n const incoming = captureTokenFromUrl(tokenParam);\n const stored = storage.get();\n\n if (launchCode || launchSession.current) {\n setUser(null);\n setStatus(\"loading\");\n if (!launchSession.current) {\n storage.clear();\n clearTenant?.();\n const controller = new AbortController();\n launchAbort.current = controller;\n // O token só é persistido depois da validação pela Central. O header\n // false neutraliza também defaults e getters de tenant sem Provider.\n launchSession.current = http.post<{ token: string }>(\"/auth/launch/exchange\", { code: launchCode },\n { signal: controller.signal, headers: { \"x-oon-tenant-id\": false, Authorization: false } },\n ).then(async (response) => {\n if (controller.signal.aborted) throw new Error(\"Launch cancelado.\");\n const token = response.data.token;\n if (!token) {\n const error: OonError = {\n code: \"APP_LAUNCH_TOKEN_MISSING\",\n message: \"A troca de abertura não retornou uma sessão.\",\n status: 502,\n };\n throw error;\n }\n const validation = await http.get<{ usuario: OonUser }>(\"/auth/validar-token\", {\n signal: controller.signal,\n headers: { Authorization: `Bearer ${token}`, \"x-oon-tenant-id\": false },\n });\n return { token, user: validation.data.usuario };\n });\n }\n const pending = launchSession.current;\n pending.then(({ token, user: next }) => {\n if (!active || launchSession.current !== pending) return;\n storage.set(token);\n applyUser(next);\n launchSession.current = null;\n }).catch((error) => {\n if (!active || launchSession.current !== pending) return;\n launchSession.current = null;\n storage.clear();\n clearTenant?.();\n applyValidationError(error);\n });\n return () => { active = false; };\n }\n\n const token = incoming ?? devToken ?? stored;\n if (token && token !== stored) storage.set(token);\n if (!token) {\n setUser(null);\n setStatus(\"unauthenticated\");\n redirectToExternalLogin();\n return;\n }\n setStatus(\"loading\");\n http.get<{ usuario: OonUser }>(\"/auth/validar-token\")\n .then((response) => {\n if (!active) return;\n applyUser(response.data.usuario);\n })\n .catch((error) => {\n if (!active) return;\n applyValidationError(error);\n });\n return () => { active = false; };\n }, [http, storage, tokenParam, devToken, redirectToExternalLogin, applyValidationError, applyUser, clearTenant, activation?.status, runtimeMode]);\n\n const roleCode = String((user as OonUser & { roleCode?: string })?.roleCode || user?.tipo || \"\");\n const roles = roleCode ? [roleCode] : [];\n const capabilities = extractCapabilities(user);\n const permissions = explicitPermissions(user) ?? capabilities;\n const hasPermission = useCallback(\n (permission?: string | string[]) => can(user, permission),\n [user],\n );\n\n const value: AuthContextValue = {\n user,\n roles,\n capabilities,\n permissions,\n status,\n isAuthenticated: status === \"authenticated\" || status === \"first-access\",\n hasPermission,\n login,\n completeFirstAccess,\n retry,\n logout: () => logout(),\n clearSession: () => logout({ redirect: false }),\n };\n\n return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;\n}\n\nexport function useOonAuth(): AuthContextValue {\n const context = useContext(AuthContext);\n if (!context) throw new Error(\"useOonAuth deve ser usado dentro de <AuthProvider> (oonCoreFront.start).\");\n return context;\n}\n\n\n","/**\n * Armazenamento de token encapsulado (Seção 6.2). Toda leitura/escrita de\n * token passa por aqui — nada de `localStorage.getItem('token')` espalhado.\n * Tudo com try/catch para JSON/localStorage inválido não derrubar a tela.\n */\nconst STORAGE_KEY = \"oon.auth.token\";\n\nexport interface TokenStorage {\n get(): string | null;\n set(token: string): void;\n clear(): void;\n}\n\nexport function createTokenStorage(namespace?: string): TokenStorage {\n const key = namespace ? `${STORAGE_KEY}.${namespace}` : STORAGE_KEY;\n\n return {\n get() {\n try {\n return window.localStorage.getItem(key);\n } catch {\n return null;\n }\n },\n set(token: string) {\n try {\n window.localStorage.setItem(key, token);\n } catch {\n /* storage indisponível (modo privado) — ignora silenciosamente. */\n }\n },\n clear() {\n try {\n window.localStorage.removeItem(key);\n } catch {\n /* noop */\n }\n },\n };\n}\n\n/**\n * Lê o token vindo do SSO via query string (?code=...) e remove da URL para\n * não vazar em histórico/logs. Retorna o token capturado, se houver.\n */\nexport function captureTokenFromUrl(tokenParam = \"code\"): string | null {\n try {\n const url = new URL(window.location.href);\n const token = url.searchParams.get(tokenParam);\n if (!token) return null;\n url.searchParams.delete(tokenParam);\n window.history.replaceState({}, document.title, url.pathname + url.search + url.hash);\n return token;\n } catch {\n return null;\n }\n}\n","import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useState,\n type ReactNode,\n} from \"react\";\nimport type { AxiosInstance } from \"axios\";\n\nexport type InstanceStatus =\n | \"loading\"\n | \"notActivated\"\n | \"validatingCode\"\n | \"codeValidated\"\n | \"submitting\"\n | \"configuring\"\n | \"active\"\n | \"suspended\"\n | \"revoked\"\n | \"error\";\n\nexport interface ActivationStatusResponse {\n role: \"root\" | \"member\";\n status: string;\n appCode: string;\n ambiente: string;\n podeAtivar: boolean;\n podeTentarNovamente: boolean;\n motivoSuspensao?: string;\n motivoRevogacao?: string;\n runtimeMode?: \"platform\" | \"local\";\n disconnected?: boolean;\n expiresAt?: string;\n}\n\ninterface ActivationContextValue {\n status: InstanceStatus;\n details: ActivationStatusResponse | null;\n refresh: () => Promise<void>;\n}\n\nconst ActivationContext = createContext<ActivationContextValue | null>(null);\n\nfunction mapStatus(data: ActivationStatusResponse): InstanceStatus {\n if ([\"ativa\", \"ativa_local\"].includes(data.status)) return \"active\";\n if (data.status === \"suspensa\") return \"suspended\";\n if (data.status === \"revogada\") return \"revoked\";\n if (data.status === \"configurando\") return \"configuring\";\n if (data.status === \"erro\" && !data.podeAtivar) return \"error\";\n return \"notActivated\";\n}\n\nexport function ActivationProvider({\n http,\n children,\n}: {\n http: AxiosInstance;\n children: ReactNode;\n}) {\n const [status, setStatus] = useState<InstanceStatus>(\"loading\");\n const [details, setDetails] = useState<ActivationStatusResponse | null>(null);\n\n const refresh = useCallback(async () => {\n setStatus(\"loading\");\n try {\n const response =\n await http.get<ActivationStatusResponse>(\"/ativacao/status\");\n setDetails(response.data);\n setStatus(mapStatus(response.data));\n } catch {\n setStatus(\"error\");\n }\n }, [http]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n return (\n <ActivationContext.Provider value={{ status, details, refresh }}>\n {children}\n </ActivationContext.Provider>\n );\n}\n\nexport function useOptionalActivation() {\n return useContext(ActivationContext);\n}\n\nexport function useActivation() {\n const context = useOptionalActivation();\n if (!context) {\n throw new Error(\n \"useActivation deve ser usado dentro de <ActivationProvider>.\",\n );\n }\n return context;\n}\n"],"mappings":"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","names":["axios","axios","createContext","useContext","useMemo","jsx","createContext","useCallback","useContext","useEffect","useRef","useState","createContext","useCallback","useContext","useState","jsx","jsx","createContext","useState","useRef","useCallback","useEffect","token","useContext"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
CoreCollection
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JXU6W3ZU.js";
|
|
4
4
|
import {
|
|
5
5
|
useOonApi
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-3JBDEAKP.js";
|
|
7
7
|
|
|
8
8
|
// src/components/CoreCurrency.tsx
|
|
9
9
|
import { Button, Flex, Heading, Stack, Text } from "@chakra-ui/react";
|
|
@@ -100,4 +100,4 @@ export {
|
|
|
100
100
|
CoreCurrency,
|
|
101
101
|
CoreAssistant
|
|
102
102
|
};
|
|
103
|
-
//# sourceMappingURL=chunk-
|
|
103
|
+
//# sourceMappingURL=chunk-5P3N4KJX.js.map
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
CoreUsersAccess,
|
|
9
9
|
MissingRenderer,
|
|
10
10
|
resolveComponent
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-JXU6W3ZU.js";
|
|
12
12
|
import {
|
|
13
13
|
OON_RESERVED_ROUTES,
|
|
14
14
|
defineOonNavigation,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
useCoreMetadata,
|
|
30
30
|
useOonApi,
|
|
31
31
|
useOonAuth
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-3JBDEAKP.js";
|
|
33
33
|
import {
|
|
34
34
|
OonThemeProvider
|
|
35
35
|
} from "./chunk-VC6NTMZS.js";
|
|
@@ -105,55 +105,89 @@ import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
|
105
105
|
import { Box as Box2, Text as Text2 } from "@chakra-ui/react";
|
|
106
106
|
|
|
107
107
|
// src/security/AcceptInvitePage.tsx
|
|
108
|
-
import { useEffect, useState } from "react";
|
|
108
|
+
import { useEffect, useState, useRef } from "react";
|
|
109
109
|
import { Box, Button, Flex, Heading, Input, Text, VStack } from "@chakra-ui/react";
|
|
110
|
-
import {
|
|
110
|
+
import { useLocation } from "react-router-dom";
|
|
111
111
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
112
112
|
function AcceptInvitePage() {
|
|
113
113
|
const { http } = useOonApi();
|
|
114
114
|
const location = useLocation();
|
|
115
|
-
const
|
|
115
|
+
const auth = useOonAuth();
|
|
116
|
+
const token = new URLSearchParams(location.hash.slice(1)).get("token") || new URLSearchParams(location.search).get("token") || "";
|
|
116
117
|
const [invitation, setInvitation] = useState(null);
|
|
118
|
+
const [sessionEmail, setSessionEmail] = useState("");
|
|
119
|
+
const operationKey = useRef(crypto.randomUUID());
|
|
120
|
+
const [registration, setRegistration] = useState({ nome: "", userDocument: "", phone: "", termsAccepted: false });
|
|
117
121
|
const [password, setPassword] = useState("");
|
|
118
122
|
const [confirm, setConfirm] = useState("");
|
|
119
123
|
const [message, setMessage] = useState(null);
|
|
124
|
+
const [inspectionAttempt, setInspectionAttempt] = useState(0);
|
|
125
|
+
const [submitting, setSubmitting] = useState(false);
|
|
120
126
|
const [done, setDone] = useState(false);
|
|
121
127
|
const [loading, setLoading] = useState(true);
|
|
122
128
|
useEffect(() => {
|
|
123
129
|
let active = true;
|
|
130
|
+
operationKey.current = crypto.randomUUID();
|
|
131
|
+
setLoading(true);
|
|
132
|
+
setInvitation(null);
|
|
133
|
+
setDone(false);
|
|
134
|
+
setMessage(null);
|
|
135
|
+
setPassword("");
|
|
136
|
+
setConfirm("");
|
|
124
137
|
if (!token) {
|
|
125
138
|
setMessage("Link de convite inv\xE1lido.");
|
|
126
139
|
setLoading(false);
|
|
127
140
|
return;
|
|
128
141
|
}
|
|
129
|
-
http.
|
|
130
|
-
if (active)
|
|
131
|
-
|
|
132
|
-
|
|
142
|
+
http.post("/core/invitations/inspect", { token }, { headers: { "x-oon-tenant-id": false } }).then((response) => {
|
|
143
|
+
if (active) {
|
|
144
|
+
setInvitation(response.data.invitation);
|
|
145
|
+
setSessionEmail(String(response.data.invitation.sessionUser?.email || "").trim().toLowerCase());
|
|
146
|
+
}
|
|
147
|
+
}).catch((error) => {
|
|
148
|
+
if (active) setMessage(error?.status === 410 ? "Este convite \xE9 inv\xE1lido, expirou, foi revogado ou j\xE1 foi utilizado. Convites anteriores ao corte tamb\xE9m podem ter sido invalidados. Solicite um novo convite ao administrador." : "N\xE3o foi poss\xEDvel validar o convite. Tente novamente.");
|
|
133
149
|
}).finally(() => {
|
|
134
150
|
if (active) setLoading(false);
|
|
135
151
|
});
|
|
136
152
|
return () => {
|
|
137
153
|
active = false;
|
|
138
154
|
};
|
|
139
|
-
}, [http, token]);
|
|
155
|
+
}, [http, token, inspectionAttempt]);
|
|
156
|
+
function clearSession() {
|
|
157
|
+
auth.clearSession();
|
|
158
|
+
setSessionEmail("");
|
|
159
|
+
}
|
|
160
|
+
const sameSession = Boolean(sessionEmail && sessionEmail === invitation?.email.toLowerCase());
|
|
161
|
+
const otherSession = Boolean(sessionEmail && !sameSession);
|
|
162
|
+
const register = invitation?.accountExists === false;
|
|
140
163
|
async function submit(event) {
|
|
141
164
|
event.preventDefault();
|
|
165
|
+
if (submitting || otherSession || auth.status === "loading") return;
|
|
142
166
|
setMessage(null);
|
|
143
|
-
if (password.length < 8) {
|
|
167
|
+
if (!sameSession && register && password.length < 8) {
|
|
144
168
|
setMessage("A senha deve possuir pelo menos 8 caracteres.");
|
|
145
169
|
return;
|
|
146
170
|
}
|
|
147
|
-
if (password !== confirm) {
|
|
171
|
+
if (!sameSession && register && password !== confirm) {
|
|
148
172
|
setMessage("As senhas informadas n\xE3o conferem.");
|
|
149
173
|
return;
|
|
150
174
|
}
|
|
175
|
+
setSubmitting(true);
|
|
151
176
|
try {
|
|
152
|
-
await http.post(
|
|
177
|
+
await http.post("/core/invitations/accept", {
|
|
178
|
+
token,
|
|
179
|
+
...invitation?.version !== void 0 ? { version: invitation.version } : {},
|
|
180
|
+
...register && invitation?.registrationRequired ? { registration: { ...registration, termsVersion: "2026-08-18", privacyVersion: "2026-08-18" } } : {},
|
|
181
|
+
intent: sameSession ? "session" : register ? "register" : "authenticate",
|
|
182
|
+
...sameSession ? {} : { password }
|
|
183
|
+
}, { headers: { "idempotency-key": operationKey.current, ...sameSession ? {} : { Authorization: false }, "x-oon-tenant-id": false } });
|
|
153
184
|
setDone(true);
|
|
154
|
-
setMessage("Convite aceito
|
|
185
|
+
setMessage("Convite aceito. Seu acesso est\xE1 dispon\xEDvel.");
|
|
155
186
|
} catch (error) {
|
|
187
|
+
if (sameSession && error?.status === 401) clearSession();
|
|
156
188
|
setMessage(error?.message || "N\xE3o foi poss\xEDvel concluir o convite.");
|
|
189
|
+
} finally {
|
|
190
|
+
setSubmitting(false);
|
|
157
191
|
}
|
|
158
192
|
}
|
|
159
193
|
return /* @__PURE__ */ jsx(Flex, { minH: "100vh", align: "center", justify: "center", bg: "#F5F8FA", px: 4, children: /* @__PURE__ */ jsx(Box, { width: "100%", maxW: "480px", bg: "white", borderWidth: "1px", borderRadius: "18px", p: { base: 6, md: 9 }, children: /* @__PURE__ */ jsxs(VStack, { align: "stretch", gap: 5, children: [
|
|
@@ -171,20 +205,50 @@ function AcceptInvitePage() {
|
|
|
171
205
|
invitation.roleName || invitation.roleCode
|
|
172
206
|
] })
|
|
173
207
|
] }),
|
|
174
|
-
|
|
175
|
-
/* @__PURE__ */ jsxs(
|
|
176
|
-
|
|
177
|
-
|
|
208
|
+
otherSession ? /* @__PURE__ */ jsxs(Box, { children: [
|
|
209
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
210
|
+
"Voc\xEA est\xE1 conectado como ",
|
|
211
|
+
sessionEmail,
|
|
212
|
+
". Este convite \xE9 para ",
|
|
213
|
+
invitation.email,
|
|
214
|
+
"."
|
|
178
215
|
] }),
|
|
179
|
-
/* @__PURE__ */
|
|
180
|
-
|
|
181
|
-
|
|
216
|
+
/* @__PURE__ */ jsx(Button, { onClick: clearSession, children: "Trocar de conta" })
|
|
217
|
+
] }) : /* @__PURE__ */ jsx("form", { onSubmit: (event) => void submit(event), children: /* @__PURE__ */ jsxs(VStack, { align: "stretch", gap: 4, children: [
|
|
218
|
+
register && invitation.registrationRequired ? /* @__PURE__ */ jsxs(Box, { children: [
|
|
219
|
+
/* @__PURE__ */ jsx(Text, { children: "Complete seu cadastro para aceitar este convite. N\xE3o ser\xE1 criada outra organiza\xE7\xE3o." }),
|
|
220
|
+
/* @__PURE__ */ jsx(Input, { "aria-label": "Nome completo", placeholder: "Nome completo", required: true, value: registration.nome, onChange: (e) => setRegistration({ ...registration, nome: e.target.value }) }),
|
|
221
|
+
/* @__PURE__ */ jsx(Input, { "aria-label": "CPF", placeholder: "CPF", required: true, value: registration.userDocument, onChange: (e) => setRegistration({ ...registration, userDocument: e.target.value }) }),
|
|
222
|
+
/* @__PURE__ */ jsx(Input, { "aria-label": "Telefone", placeholder: "Telefone com DDD", required: true, value: registration.phone, onChange: (e) => setRegistration({ ...registration, phone: e.target.value }) }),
|
|
223
|
+
/* @__PURE__ */ jsxs("label", { children: [
|
|
224
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", required: true, checked: registration.termsAccepted, onChange: (e) => setRegistration({ ...registration, termsAccepted: e.target.checked }) }),
|
|
225
|
+
" Aceito os termos e a pol\xEDtica de privacidade da plataforma (2026-08-18)."
|
|
226
|
+
] })
|
|
227
|
+
] }) : null,
|
|
228
|
+
!sameSession ? /* @__PURE__ */ jsxs(Box, { children: [
|
|
229
|
+
/* @__PURE__ */ jsx(Text, { mb: 1, fontSize: "sm", fontWeight: "600", children: register ? "Nova senha" : "Senha atual" }),
|
|
230
|
+
/* @__PURE__ */ jsx(Input, { "aria-label": register ? "Nova senha" : "Senha atual", type: "password", autoComplete: register ? "new-password" : "current-password", value: password, onChange: (event) => setPassword(event.target.value), required: true })
|
|
231
|
+
] }) : /* @__PURE__ */ jsxs(Text, { children: [
|
|
232
|
+
"Voc\xEA est\xE1 conectado como ",
|
|
233
|
+
sessionEmail,
|
|
234
|
+
". Confirme o aceite para liberar este acesso."
|
|
182
235
|
] }),
|
|
183
|
-
/* @__PURE__ */
|
|
236
|
+
!sameSession && register ? /* @__PURE__ */ jsxs(Box, { children: [
|
|
237
|
+
/* @__PURE__ */ jsx(Text, { mb: 1, fontSize: "sm", fontWeight: "600", children: "Confirmar senha" }),
|
|
238
|
+
/* @__PURE__ */ jsx(Input, { "aria-label": "Confirmar senha", type: "password", autoComplete: "new-password", value: confirm, onChange: (event) => setConfirm(event.target.value), required: true })
|
|
239
|
+
] }) : null,
|
|
240
|
+
!register && !sameSession ? /* @__PURE__ */ jsx(Text, { fontSize: "sm", children: "Use a senha atual da sua conta Oon. Se esqueceu a senha, recupere-a pelo login da plataforma e depois reabra este convite." }) : null,
|
|
241
|
+
invitation.blockedReason ? /* @__PURE__ */ jsxs(Text, { role: "alert", children: [
|
|
242
|
+
"O aceite est\xE1 indispon\xEDvel (",
|
|
243
|
+
invitation.blockedReason,
|
|
244
|
+
"). Solicite regulariza\xE7\xE3o ao administrador."
|
|
245
|
+
] }) : null,
|
|
246
|
+
/* @__PURE__ */ jsx(Button, { type: "submit", disabled: submitting || auth.status === "loading" || Boolean(invitation.allowedActions && !invitation.allowedActions.includes("accept")), children: submitting ? "Aceitando\u2026" : "Aceitar convite" })
|
|
184
247
|
] }) })
|
|
185
248
|
] }) : null,
|
|
186
249
|
message ? /* @__PURE__ */ jsx(Box, { role: "status", bg: done ? "green.50" : "red.50", borderRadius: "md", p: 3, children: /* @__PURE__ */ jsx(Text, { fontSize: "sm", children: message }) }) : null,
|
|
187
|
-
|
|
250
|
+
!loading && !invitation && token ? /* @__PURE__ */ jsx(Button, { onClick: () => setInspectionAttempt((value2) => value2 + 1), children: "Tentar novamente" }) : null,
|
|
251
|
+
done ? /* @__PURE__ */ jsx(Button, { asChild: true, children: /* @__PURE__ */ jsx("a", { href: sameSession ? "/" : "/login", children: sameSession ? "Abrir aplicativo" : "Ir para o login" }) }) : null
|
|
188
252
|
] }) }) });
|
|
189
253
|
}
|
|
190
254
|
|
|
@@ -212,9 +276,9 @@ function AcceptInviteCentralPage() {
|
|
|
212
276
|
}
|
|
213
277
|
|
|
214
278
|
// src/security/OnboardingPage.tsx
|
|
215
|
-
import { useEffect as useEffect3, useRef, useState as useState3 } from "react";
|
|
279
|
+
import { useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
|
|
216
280
|
import { Box as Box3, Button as Button2, Flex as Flex2, Heading as Heading2, Input as Input2, Text as Text3, VStack as VStack2 } from "@chakra-ui/react";
|
|
217
|
-
import { Link
|
|
281
|
+
import { Link, useLocation as useLocation2 } from "react-router-dom";
|
|
218
282
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
219
283
|
var TERMS_VERSION = "2026-08-18";
|
|
220
284
|
var PRIVACY_VERSION = "2026-08-18";
|
|
@@ -234,7 +298,7 @@ function OnboardingPage({ baseUrl, mode }) {
|
|
|
234
298
|
const [accepted, setAccepted] = useState3(false);
|
|
235
299
|
const [message, setMessage] = useState3("");
|
|
236
300
|
const [busy, setBusy] = useState3(false);
|
|
237
|
-
const confirmationToken =
|
|
301
|
+
const confirmationToken = useRef2(null);
|
|
238
302
|
useEffect3(() => {
|
|
239
303
|
if (mode !== "confirm") return;
|
|
240
304
|
const token = new URLSearchParams(location.search).get("token");
|
|
@@ -282,7 +346,7 @@ function OnboardingPage({ baseUrl, mode }) {
|
|
|
282
346
|
/* @__PURE__ */ jsx3(Button2, { type: "submit", bg: "#07262E", color: "white", disabled: busy || !accepted, children: busy ? "Enviando..." : "Criar acesso" })
|
|
283
347
|
] }) }) : null,
|
|
284
348
|
message ? /* @__PURE__ */ jsx3(Box3, { role: "status", bg: "blue.50", color: "blue.800", borderRadius: "10px", p: 4, children: message }) : null,
|
|
285
|
-
/* @__PURE__ */ jsx3(Text3, { fontSize: "sm", children: /* @__PURE__ */ jsx3(
|
|
349
|
+
/* @__PURE__ */ jsx3(Text3, { fontSize: "sm", children: /* @__PURE__ */ jsx3(Link, { to: "/login", children: "Voltar para o login" }) })
|
|
286
350
|
] }) }) });
|
|
287
351
|
}
|
|
288
352
|
|
|
@@ -710,7 +774,7 @@ function Sidebar({ app, menu, registry }) {
|
|
|
710
774
|
// package.json
|
|
711
775
|
var package_default = {
|
|
712
776
|
name: "@oondemand/oon-core-front",
|
|
713
|
-
version: "0.7.
|
|
777
|
+
version: "0.7.8",
|
|
714
778
|
repository: {
|
|
715
779
|
type: "git",
|
|
716
780
|
url: "git+https://github.com/oondemand/oon-platform.git",
|
|
@@ -1182,7 +1246,7 @@ function AppAccessGuard({ children }) {
|
|
|
1182
1246
|
// src/security/LoginPage.tsx
|
|
1183
1247
|
import { useState as useState6 } from "react";
|
|
1184
1248
|
import { Box as Box7, Button as Button5, Flex as Flex6, Heading as Heading4, Input as Input3, SimpleGrid, Text as Text7, VStack as VStack4 } from "@chakra-ui/react";
|
|
1185
|
-
import { Link as
|
|
1249
|
+
import { Link as Link2, Navigate as Navigate2, useLocation as useLocation4 } from "react-router-dom";
|
|
1186
1250
|
import { jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1187
1251
|
function tenantOptions(error) {
|
|
1188
1252
|
const details = error.details;
|
|
@@ -1299,7 +1363,7 @@ function LoginPage({ app, onboardingEnabled = false }) {
|
|
|
1299
1363
|
tenants.length <= 1 ? /* @__PURE__ */ jsx12(Button5, { type: "submit", bg: "#07262E", color: "white", _hover: { bg: "#0B3843" }, disabled: submitting || !email.trim() || !password, children: submitting ? "Validando acesso..." : "Entrar" }) : null,
|
|
1300
1364
|
app.kind === "portal-cockpit" && onboardingEnabled && tenants.length <= 1 ? /* @__PURE__ */ jsxs8(Text7, { textAlign: "center", fontSize: "sm", color: "gray.600", children: [
|
|
1301
1365
|
"Ainda n\xE3o possui acesso? ",
|
|
1302
|
-
/* @__PURE__ */ jsx12(
|
|
1366
|
+
/* @__PURE__ */ jsx12(Link2, { to: "/cadastro", children: "Criar conta" })
|
|
1303
1367
|
] }) : null
|
|
1304
1368
|
] }) }) }) });
|
|
1305
1369
|
}
|
|
@@ -1893,7 +1957,7 @@ function OonApp({ config }) {
|
|
|
1893
1957
|
getTenantId: () => tenantStorage2.get(),
|
|
1894
1958
|
onUnauthorized: () => {
|
|
1895
1959
|
storage2.clear();
|
|
1896
|
-
if (config.runtimeMode === "local") return;
|
|
1960
|
+
if (config.runtimeMode === "local" || window.location.pathname === "/accept-invite") return;
|
|
1897
1961
|
if (externalLoginUrl) {
|
|
1898
1962
|
window.location.href = externalLoginUrl;
|
|
1899
1963
|
return;
|
|
@@ -2103,4 +2167,4 @@ export {
|
|
|
2103
2167
|
appDefinitionToConfig,
|
|
2104
2168
|
startOonApp
|
|
2105
2169
|
};
|
|
2106
|
-
//# sourceMappingURL=chunk-
|
|
2170
|
+
//# sourceMappingURL=chunk-7XXROGIF.js.map
|