@geekapps/auth-nextjs 0.24.0 → 0.26.0
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 +58 -4
- package/dist/actions.d.ts +18 -2
- package/dist/actions.js +44 -4
- package/dist/actions.js.map +1 -1
- package/dist/client.d.ts +75 -4
- package/dist/client.js +48 -10
- package/dist/client.js.map +1 -1
- package/dist/connections.d.ts +2 -1
- package/dist/connections.js +12 -21
- package/dist/connections.js.map +1 -1
- package/dist/middleware.js.map +1 -1
- package/dist/server.d.ts +23 -9
- package/dist/server.js +22 -8
- package/dist/server.js.map +1 -1
- package/dist/typegen.d.ts +8 -1
- package/dist/typegen.js +10 -4
- package/dist/typegen.js.map +1 -1
- package/package.json +5 -9
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\n/**\n * A sessão não vale mais: expirou ou foi revogada. O estado local já foi\n * limpo quando este erro é lançado — o tratamento normal é levar ao login.\n */\nexport class GeekappsSessionExpiredError extends Error {\n readonly code = \"session_expired\" as const;\n\n constructor(message = \"A sessão expirou ou foi revogada. Entre novamente.\") {\n super(message);\n this.name = \"GeekappsSessionExpiredError\";\n }\n}\n\nexport type UserStatus = \"active\" | \"inactive\" | \"suspended\";\nexport type OrganizationStatus = \"active\" | \"inactive\" | \"suspended\";\nexport type OAuthClientType = \"public\" | \"confidential\";\n\nexport type AuthResult<T = unknown> =\n | { success: true; data: T }\n | {\n success: false;\n error: string;\n status?: number;\n /** Código de erro da API (ex.: \"legal_fields_required\", \"invalid_tax_id\"). */\n code?: string;\n /** Campos obrigatórios que faltaram (ex.: \"legalName\", \"legalAddress.city\"). */\n missingFields?: string[];\n };\n\n/** Erro de request com o corpo estruturado da API (code/missingFields). */\nexport class GeekappsApiError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly code?: string,\n readonly missingFields?: string[],\n ) {\n super(message);\n this.name = \"GeekappsApiError\";\n }\n}\n\n/** standard: organização comum. legal: pessoa jurídica associada a um Tax ID (CNPJ ou genérico). */\nexport type OrganizationType = \"standard\" | \"legal\";\nexport type TaxIdType = \"br_cnpj\" | \"generic\";\n\nexport type OrganizationLegalAddress = {\n street?: string | null;\n number?: string | null;\n complement?: string | null;\n district?: string | null;\n city?: string | null;\n state?: string | null;\n postalCode?: string | null;\n /** ISO 3166-1 alpha-2 */\n country?: string | null;\n};\n\nexport type OrganizationLegalData = {\n legalName: string | null;\n tradeName: string | null;\n legalEmail: string | null;\n legalPhone: string | null;\n legalAddress: OrganizationLegalAddress | null;\n};\n\nexport type TaxIdLookupResult = {\n taxId: string;\n taxIdType: TaxIdType;\n taxIdCountry: string | null;\n valid: boolean;\n /** Já existe uma organização deste app com esse Tax ID. */\n alreadyRegistered: boolean;\n /** false quando a fonte pública estava indisponível — preencha manualmente. */\n lookupAvailable: boolean;\n found: boolean;\n registrationStatus: string | null;\n suggestedName: string | null;\n data: OrganizationLegalData;\n /** Obrigatórios que a consulta não conseguiu preencher — peça ao usuário. */\n missingFields: string[];\n};\n\nexport type User = {\n id: string;\n email: string;\n name: string | null;\n phone: string | null;\n imageUrl: string | null;\n status?: UserStatus;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type ConnectedAccount = {\n id: string;\n sessionId?: string;\n isActive: boolean;\n user: User;\n};\n\nexport type Permission = {\n id: string;\n applicationId?: string | null;\n key: string;\n name: string;\n description: string | null;\n category: string | null;\n isSystem: boolean;\n isActive: boolean;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type RolePermission = {\n permissionDefinition: Permission;\n};\n\nexport type Role = {\n id: string;\n applicationId?: string | null;\n /** Present only on custom roles */\n organizationId?: string | null;\n /** \"system\" | \"custom\" */\n type?: string;\n key: string;\n name: string;\n description: string | null;\n isSystem?: boolean;\n isDefault?: boolean;\n isActive: boolean;\n permissions: RolePermission[];\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type RoleAssignment = {\n id: string;\n roleDefinitionId?: string | null;\n customRoleId?: string | null;\n roleDefinition?: Role | null;\n customRole?: Role | null;\n};\n\n/** Role de um membro, como o auth-server devolve. */\nexport type MemberRole = {\n id: string;\n key: string;\n name: string;\n isDefault: boolean;\n isActive: boolean;\n};\n\n/** Convite recebido pelo usuário logado (GET /me/invites). Nunca traz o token do e-mail. */\nexport type MyOrganizationInvite = {\n id: string;\n organizationId: string;\n email: string;\n status: \"pending\";\n expiresAt: string;\n createdAt: string;\n role: { id: string; key: string; name: string } | null;\n organization: { id: string; name: string; slug: string; imageUrl: string | null; applicationId: string };\n};\n\nexport type OrganizationMember = {\n id: string;\n organizationId?: string;\n userId?: string;\n status?: OrganizationStatus;\n createdAt?: string | Date;\n user: User;\n /** Role do membro na organização (null = sem role atribuída). */\n role?: MemberRole | null;\n /** @deprecated formato antigo — o auth-server devolve `role`. */\n roleAssignments?: RoleAssignment[];\n};\n\n/** Participação do usuário logado numa organização (GET /organizations/:id/members/me). */\nexport type OrganizationMembership = {\n organizationId: string;\n membershipId: string | null;\n status: OrganizationStatus;\n /** Dono da organização: passa em qualquer checagem de permissão. */\n isOwner: boolean;\n role: MemberRole | null;\n /** Permissões efetivas da role (keys). Para o dono, use `isOwner`. */\n permissions: string[];\n joinedAt: string | Date | null;\n};\n\nexport type OrganizationInvite = {\n id: string;\n organizationId: string;\n email: string;\n /**\n * Role que o convidado assume ao aceitar. Vem aninhada do auth-server (não\n * como roleId solto) — null quando o convite não fixa nenhuma e o membro\n * cai na role default da organização.\n */\n role: { id: string; key: string; name: string } | null;\n /** @deprecated use `role.id` — o auth-server não devolve este campo. */\n roleId?: string | null;\n status: \"pending\" | \"accepted\" | \"expired\" | \"revoked\";\n expiresAt: string | Date;\n acceptedAt?: string | Date | null;\n createdAt?: string | Date;\n redirectUri?: string | null;\n emailTitle?: string | null;\n emailSubtitle?: string | null;\n emailMessage?: string | null;\n};\n\nexport type MemberInviteInput = {\n email: string;\n roleId?: string;\n /**\n * URI pra onde o link do e-mail manda o usuário — precisa estar cadastrada\n * em Application.redirectUris (mesma validação do /authorize). Este app\n * deve expor uma rota nessa URI que trata o `?invite_token=` anexado (ver\n * useJoinRequests/inviteApi.preview|accept|reject abaixo).\n */\n redirectUri: string;\n emailTitle?: string;\n emailSubtitle?: string;\n emailMessage?: string;\n};\n\nexport type AddMemberInput = {\n userId: string;\n roleId?: string;\n};\n\nexport type UpdateMemberInput = {\n status?: \"active\" | \"inactive\" | \"suspended\";\n roleId?: string | null;\n};\n\n/** @deprecated use UpdateMemberInput */\nexport type UpdateMemberRoleInput = {\n roleId: string;\n};\n\nexport type PublicOrganization = {\n id: string;\n name: string;\n slug: string;\n description: string | null;\n imageUrl: string | null;\n createdAt: string | Date;\n};\n\nexport type OrganizationInvitePreview =\n | {\n alreadyAccepted: true;\n organizationId: string;\n organizationName: string;\n applicationName: string;\n applicationImageUrl: string | null;\n applicationImageFileId: string | null;\n organizationImageUrl: string | null;\n organizationImageFileId: string | null;\n websiteUrl: string | null;\n }\n | {\n alreadyAccepted?: false;\n email: string;\n organizationId: string;\n organizationName: string;\n applicationName: string;\n applicationId: string;\n applicationImageUrl: string | null;\n applicationImageFileId: string | null;\n organizationImageUrl: string | null;\n organizationImageFileId: string | null;\n websiteUrl: string | null;\n redirectUri: string | null;\n appStoreUrl: string | null;\n playStoreUrl: string | null;\n currentAccount: { email: string; name: string | null } | null;\n };\n\nexport type AcceptInviteResult =\n | { success: true; organizationId: string; organizationName: string; websiteUrl: string | null }\n | { success: false; wrongAccount: true; currentEmail: string; invitedEmail: string }\n | { success: false; wrongAccount: false; loginRequired: true }\n | { success: false; wrongAccount: false; loginRequired: false; error: string };\n\nexport type JoinRequestStatus = \"pending\" | \"approved\" | \"rejected\" | \"cancelled\";\n\nexport type OrganizationJoinRequest = {\n id: string;\n organizationId: string;\n userId: string;\n status: JoinRequestStatus;\n message: string | null;\n reviewedByUserId: string | null;\n reviewedAt: string | null;\n createdAt: string | Date;\n updatedAt: string | Date;\n};\n\nexport type OrganizationOwnedApplication = {\n id: string;\n name: string;\n description: string | null;\n imageUrl: string | null;\n type?: OAuthClientType;\n organizationId: string;\n isFirstParty: boolean;\n ssoEnabled: boolean;\n status?: \"active\" | \"inactive\" | \"suspended\";\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type Organization = {\n id: string;\n name: string;\n description: string | null;\n slug: string;\n domain: string | null;\n imageUrl: string | null;\n faviconUrl: string | null;\n status: OrganizationStatus;\n /** \"private\" (padrão) nunca sai em listPublicOrganizations(); \"public\" sai, e aceita join requests. */\n visibility?: \"public\" | \"private\";\n type?: OrganizationType;\n taxId?: string | null;\n taxIdType?: TaxIdType | null;\n taxIdCountry?: string | null;\n legalName?: string | null;\n tradeName?: string | null;\n legalEmail?: string | null;\n legalPhone?: string | null;\n legalAddress?: OrganizationLegalAddress | null;\n taxIdVerifiedAt?: string | Date | null;\n members?: OrganizationMember[];\n ownedApplications?: OrganizationOwnedApplication[];\n applicationLinks?: Array<{\n id: string;\n status: OrganizationStatus;\n createdAt?: string | Date;\n application: OrganizationOwnedApplication;\n }>;\n createdAt: string | Date;\n updatedAt: string | Date;\n};\n\nexport type SessionApplication = {\n id: string;\n createdAt: string | Date;\n expiresAt: string | Date;\n application: {\n id: string;\n name: string;\n organizationId: string;\n };\n};\n\nexport type UserSession = {\n id: string;\n userId: string;\n organizationId: string | null;\n deviceAgent: string | null;\n deviceId: string | null;\n deviceName: string | null;\n ip: string | null;\n authState?: unknown;\n authTime?: string | Date;\n expiresAt: string | Date;\n createdAt: string | Date;\n updatedAt: string | Date;\n user?: User;\n applicationSessions?: SessionApplication[];\n};\n\nexport type UserInput = {\n name?: string | null;\n email?: string;\n phone?: string | null;\n imageUrl?: string | null;\n password?: string;\n organizationId?: string | null;\n status?: UserStatus;\n};\n\nexport type OrganizationInput = {\n name: string;\n description?: string | null;\n slug: string;\n domain?: string | null;\n imageUrl?: string | null;\n faviconUrl?: string | null;\n visibility?: \"public\" | \"private\";\n /** \"legal\" exige taxId; dados da empresa (CNPJ) são buscados automaticamente no servidor. */\n type?: OrganizationType;\n taxId?: string | null;\n /** Padrão: \"br_cnpj\". */\n taxIdType?: TaxIdType | null;\n /** Obrigatório para taxIdType \"generic\". */\n taxIdCountry?: string | null;\n} & Partial<OrganizationLegalData>;\n\nexport type OrganizationUpdateInput = Partial<\n Omit<OrganizationInput, \"type\" | \"taxId\" | \"taxIdType\" | \"taxIdCountry\">\n> & {\n status?: OrganizationStatus;\n};\n\nexport type RoleInput = {\n /** Opcional: sem ele, usa a organização ativa. */\n organizationId?: string;\n applicationId?: string | null;\n key: string;\n name: string;\n description?: string | null;\n permissionDefinitionIds?: string[];\n};\n\nexport type RoleUpdateInput = {\n name?: string;\n description?: string | null;\n isActive?: boolean;\n permissionDefinitionIds?: string[];\n};\n\nexport type PermissionInput = {\n applicationId?: string | null;\n key: string;\n name: string;\n description?: string | null;\n category?: string | null;\n};\n\nexport type PermissionUpdateInput = {\n name?: string;\n description?: string | null;\n category?: string | null;\n isActive?: boolean;\n};\n\n/**\n * OIDC `prompt` values understood by the Geekapps Auth Server. These control\n * whether — and how — the IDP shows UI during `signIn()`/`signUp()`/`addAccount()`.\n *\n * - `\"login\"` — Forces the login screen, even if the user already has an active\n * session. Use this for a fresh login, unrelated to whatever session already\n * exists (equivalent to the old `silentLogin: false`).\n * - `\"select_account\"` — Shows the account picker so the user can choose among\n * their connected accounts, or add a new one. Use this when you want to let\n * the user switch accounts explicitly.\n * - `\"none\"` — Never shows any UI. The IDP authenticates silently if there is\n * exactly one active session (and no other interaction — like consent or a\n * security check — is pending); otherwise it fails immediately with an OIDC\n * error (`login_required`, `account_selection_required`, `consent_required`,\n * or `interaction_required`) instead of prompting the user. Use this for\n * silent-auth checks (e.g. \"is the user still logged in?\") where you don't\n * want to interrupt them with a screen.\n * - `\"consent\"` — Forces the consent screen even if the user already granted\n * the requested scopes before.\n *\n * Omitting `prompt` entirely runs the IDP's default flow: reuse a single\n * existing session silently, ask the user to pick when there are multiple\n * connected accounts, or show the login screen when there's none.\n */\nexport type OidcPrompt = \"login\" | \"select_account\" | \"none\" | \"consent\";\n\nexport type SignInOptions = {\n redirectTo?: string;\n authorizationFlowId?: string;\n /**\n * Controls whether the IDP shows UI, and which screen, during sign-in. See\n * {@link OidcPrompt} for what each value does. Omit it to run the default flow.\n */\n prompt?: OidcPrompt;\n /**\n * @deprecated Use `prompt: \"login\"` instead. Kept for backwards compatibility —\n * `silentLogin: false` is equivalent to `prompt: \"login\"`.\n */\n silentLogin?: boolean;\n};\n\nexport type SignInInput = SignInOptions | MouseEvent<HTMLElement>;\n\nexport type CallbackUrlOptions = SignInOptions & {\n callbackUrl?: string;\n};\n\nexport type PermissionCheckOptions = {\n permission: string;\n organizationId?: string | null;\n applicationId?: string | null;\n resourceId?: string | null;\n};\n\nexport type LoginResponse = {\n user: User;\n redirectTo?: string | null;\n};\n\nexport type RegisterResponse = User;\n\nexport type GeekappsAuthProviderProps = {\n children: ReactNode;\n basePath?: string;\n initialUser?: User | null;\n initialOrganizations?: Organization[];\n initialCurrentOrgId?: string | null;\n};\n\ntype RequestOptions = {\n body?: unknown;\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n};\n\nfunction normalizeBasePath(basePath: string) {\n return basePath.endsWith(\"/\") ? basePath.slice(0, -1) : basePath;\n}\n\nfunction buildUrl(basePath: string, path: string) {\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n return `${normalizeBasePath(basePath)}${normalizedPath}`;\n}\n\nasync function parseError(response: Response) {\n const data = await response.json().catch(() => null);\n return (\n data?.error_description ??\n data?.error ??\n data?.message ??\n `Request failed with status ${response.status}`\n );\n}\n\nfunction redirectTo(path: string) {\n window.location.assign(path);\n}\n\nfunction isMouseEvent(value: unknown): value is MouseEvent<HTMLElement> {\n return Boolean(value && typeof value === \"object\" && \"preventDefault\" in value);\n}\n\nfunction normalizeSignInOptions(input?: SignInInput): SignInOptions | undefined {\n if (!input) return undefined;\n if (isMouseEvent(input)) {\n input.preventDefault();\n return undefined;\n }\n return input;\n}\n\n\ntype ClientActionOptions = {\n basePath?: string;\n};\n\nasync function clientRequest<T>(\n path: string,\n options: RequestOptions = {},\n basePath = \"/api/auth\",\n): Promise<T> {\n const response = await fetch(buildUrl(basePath, path), {\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n credentials: \"include\",\n headers:\n options.body === undefined\n ? undefined\n : {\n \"content-type\": \"application/json\",\n },\n method: options.method ?? \"GET\",\n });\n\n if (!response.ok) {\n throw new Error(await parseError(response));\n }\n\n if (response.status === 204) {\n return null as T;\n }\n\n return (await response.json()) as T;\n}\n\nasync function toStandaloneAuthResult<T>(\n fn: () => Promise<T>,\n): Promise<AuthResult<T>> {\n try {\n return {\n success: true,\n data: await fn(),\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Auth request failed\",\n };\n }\n}\n\nexport async function loginWithPassword(\n params: {\n identifier?: string;\n email?: string;\n phone?: string;\n password: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult<LoginResponse>> {\n return toStandaloneAuthResult(async () => {\n const data = await clientRequest<LoginResponse>(\n \"/login/password\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n );\n\n if (params.redirectTo ?? data.redirectTo) {\n redirectTo(params.redirectTo ?? data.redirectTo!);\n }\n\n return data;\n });\n}\n\nexport async function registerWithPassword(\n params: {\n name: string;\n email: string;\n phone?: string;\n imageUrl?: string;\n address?: Record<string, unknown>;\n password: string;\n redirectTo?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult<RegisterResponse>> {\n return toStandaloneAuthResult(async () => {\n const data = await clientRequest<RegisterResponse>(\n \"/register/password\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n );\n\n if (params.redirectTo) {\n redirectTo(params.redirectTo);\n }\n\n return data;\n });\n}\n\nexport function startGoogleLogin(\n params?: CallbackUrlOptions,\n options?: ClientActionOptions,\n) {\n const basePath = options?.basePath ?? \"/api/auth\";\n const url = new URL(buildUrl(basePath, \"/login/google\"), window.location.origin);\n\n if (params?.callbackUrl) {\n url.searchParams.set(\"callbackUrl\", params.callbackUrl);\n }\n\n if (params?.redirectTo) {\n url.searchParams.set(\"redirectTo\", params.redirectTo);\n }\n\n if (params?.authorizationFlowId) {\n url.searchParams.set(\"flow_id\", params.authorizationFlowId);\n }\n\n redirectTo(url.toString());\n}\n\nexport async function requestPasswordlessLink(\n params: {\n email: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n callbackUrl?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult> {\n return toStandaloneAuthResult(() =>\n clientRequest(\n \"/passwordless/link\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n ),\n );\n}\n\nexport type GeekappsAuthContextValue = {\n basePath: string;\n user: User | null;\n isAuthenticated: boolean;\n isLoading: boolean;\n accounts: ConnectedAccount[];\n isLoadingAccounts: boolean;\n organizations: Organization[];\n currentOrg: Organization | null;\n currentOrgId: string | null;\n isLoadingOrganizations: boolean;\n\n request: <T>(path: string, options?: RequestOptions) => Promise<T>;\n\n signIn: (options?: SignInInput) => Promise<void>;\n signUp: (options?: SignInInput) => Promise<void>;\n addAccount: (options?: SignInInput) => Promise<void>;\n signOut: () => Promise<void>;\n signOutAll: () => Promise<void>;\n refreshUser: () => Promise<void>;\n refreshAccounts: () => Promise<void>;\n switchAccount: (sessionId: string, options?: SignInOptions) => Promise<void>;\n\n loginWithPassword: (params: {\n identifier?: string;\n email?: string;\n phone?: string;\n password: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n }) => Promise<AuthResult<LoginResponse>>;\n registerWithPassword: (params: {\n name: string;\n email: string;\n phone?: string;\n imageUrl?: string;\n address?: Record<string, unknown>;\n password: string;\n redirectTo?: string;\n }) => Promise<AuthResult<RegisterResponse>>;\n startGoogleLogin: (params?: CallbackUrlOptions) => void;\n requestPasswordlessLink: (params: {\n email: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n callbackUrl?: string;\n }) => Promise<AuthResult>;\n\n refreshOrganizations: () => Promise<void>;\n setCurrentOrg: (organizationId: string | null) => Promise<void>;\n createOrganization: (input: OrganizationInput) => Promise<AuthResult<Organization>>;\n /** Valida o Tax ID e busca os dados da empresa (CNPJ) para pré-preencher a criação. */\n lookupTaxId: (value: string, type?: TaxIdType) => Promise<AuthResult<TaxIdLookupResult>>;\n updateOrganization: (id: string, input: OrganizationUpdateInput) => Promise<AuthResult<Organization>>;\n deleteOrganization: (id: string) => Promise<AuthResult<null>>;\n hasPermission: (options: PermissionCheckOptions) => Promise<boolean>;\n /** Participação do usuário na organização ativa (role, permissões, dono). Carregada sozinha ao trocar de organização. */\n currentMembership: OrganizationMembership | null;\n isLoadingMembership: boolean;\n /** Participação do usuário numa organização qualquer (padrão: a ativa). */\n getMyMembership: (organizationId?: string) => Promise<OrganizationMembership | null>;\n refreshMembership: () => Promise<void>;\n\n /** Organizações públicas e ativas deste app — nunca inclui privadas, não exige membership. Separado de `organizations` (só as do próprio usuário). */\n listPublicOrganizations: () => Promise<PublicOrganization[]>;\n\n requestToJoin: (organizationId: string, input?: { message?: string | null }) => Promise<AuthResult<OrganizationJoinRequest>>;\n getMyJoinRequest: (organizationId: string) => Promise<OrganizationJoinRequest | null>;\n cancelJoinRequest: (organizationId: string) => Promise<AuthResult<null>>;\n listJoinRequests: (organizationId: string) => Promise<OrganizationJoinRequest[]>;\n approveJoinRequest: (organizationId: string, requestId: string) => Promise<AuthResult<OrganizationJoinRequest>>;\n rejectJoinRequest: (organizationId: string, requestId: string) => Promise<AuthResult<OrganizationJoinRequest>>;\n\n /** Preview do convite por token — funciona com ou sem sessão (currentAccount vem null se deslogado). */\n getInvitePreview: (token: string) => Promise<OrganizationInvitePreview>;\n /** Aceita o convite. loginRequired:true significa que signIn() precisa rodar antes. */\n acceptInvite: (token: string) => Promise<AcceptInviteResult>;\n /** Recusa o convite — não exige estar logado. */\n rejectInvite: (token: string) => Promise<{ success: true } | { success: false; error: string }>;\n /** Convites pendentes para o e-mail do usuário logado (só deste app). */\n listMyInvites: () => Promise<MyOrganizationInvite[]>;\n /** Aceita pelo id — sem token do e-mail; só o próprio convidado consegue. */\n acceptInviteById: (inviteId: string) => Promise<{ success: true; organizationId: string; organizationName: string }>;\n /** Recusa pelo id — só o próprio convidado consegue. */\n rejectInviteById: (inviteId: string) => Promise<void>;\n\n listUsers: (params?: { organizationId?: string | null }) => Promise<User[]>;\n getUser: (id: string) => Promise<User>;\n createUser: (input: UserInput) => Promise<AuthResult<User>>;\n updateUser: (id: string, input: UserInput) => Promise<AuthResult<User>>;\n deleteUser: (id: string) => Promise<AuthResult<null>>;\n\n /**\n * Roles da organização. `organizationId` é opcional: sem ele, usa a\n * organização ativa. `applicationId`/`type` são aceitos por\n * compatibilidade e não filtram nada — a separação system/custom vem no\n * próprio retorno.\n */\n listRoles: (params?: { organizationId?: string; applicationId?: string; type?: \"system\" | \"custom\" | \"all\" }) => Promise<{ systemRoles: Role[]; customRoles: Role[] }>;\n getRole: (id: string, type?: \"system\" | \"custom\", organizationId?: string) => Promise<Role>;\n createRole: (input: RoleInput) => Promise<AuthResult<Role>>;\n updateRole: (id: string, input: RoleUpdateInput, organizationId?: string) => Promise<AuthResult<Role>>;\n deleteRole: (id: string, organizationId?: string) => Promise<AuthResult<null>>;\n\n listPermissions: (params?: { applicationId?: string; roleId?: string | null }) => Promise<Permission[]>;\n createPermission: (input: PermissionInput) => Promise<AuthResult<Permission>>;\n updatePermission: (id: string, input: PermissionUpdateInput) => Promise<AuthResult<Permission>>;\n deletePermission: (id: string) => Promise<AuthResult<null>>;\n\n listUserSessions: (params?: { userId?: string; organizationId?: string | null }) => Promise<UserSession[]>;\n revokeUserSession: (sessionId: string) => Promise<AuthResult<null>>;\n\n listMembers: (organizationId: string) => Promise<OrganizationMember[]>;\n getMember: (organizationId: string, memberId: string) => Promise<OrganizationMember>;\n addMember: (organizationId: string, input: AddMemberInput) => Promise<AuthResult<OrganizationMember>>;\n updateMember: (\n organizationId: string,\n memberId: string,\n input: UpdateMemberInput,\n ) => Promise<AuthResult<OrganizationMember>>;\n /** @deprecated use updateMember */\n updateMemberRole: (\n organizationId: string,\n memberId: string,\n input: UpdateMemberRoleInput,\n ) => Promise<AuthResult<OrganizationMember>>;\n removeMember: (organizationId: string, memberId: string) => Promise<AuthResult<null>>;\n inviteMember: (organizationId: string, input: MemberInviteInput) => Promise<AuthResult<OrganizationInvite>>;\n listInvites: (organizationId: string) => Promise<OrganizationInvite[]>;\n revokeInvite: (organizationId: string, inviteId: string) => Promise<AuthResult<null>>;\n};\n\nexport type UseOrgResult = Pick<\n GeekappsAuthContextValue,\n | \"organizations\"\n | \"currentOrg\"\n | \"currentOrgId\"\n | \"isLoadingOrganizations\"\n | \"refreshOrganizations\"\n | \"setCurrentOrg\"\n | \"createOrganization\"\n | \"lookupTaxId\"\n | \"updateOrganization\"\n | \"deleteOrganization\"\n | \"hasPermission\"\n | \"currentMembership\"\n | \"isLoadingMembership\"\n | \"getMyMembership\"\n | \"refreshMembership\"\n>;\n\nexport type UseAccountsResult = Pick<\n GeekappsAuthContextValue,\n \"accounts\" | \"addAccount\" | \"isLoadingAccounts\" | \"refreshAccounts\" | \"switchAccount\"\n>;\n\nexport type UseUsersResult = Pick<\n GeekappsAuthContextValue,\n \"listUsers\" | \"getUser\" | \"createUser\" | \"updateUser\" | \"deleteUser\"\n>;\n\nexport type UseRolesResult = Pick<\n GeekappsAuthContextValue,\n \"listRoles\" | \"getRole\" | \"createRole\" | \"updateRole\" | \"deleteRole\"\n>;\n\nexport type UsePermissionsResult = Pick<\n GeekappsAuthContextValue,\n \"listPermissions\" | \"createPermission\" | \"updatePermission\" | \"deletePermission\"\n>;\n\nexport type UseSessionsResult = Pick<\n GeekappsAuthContextValue,\n \"listUserSessions\" | \"revokeUserSession\"\n>;\n\nexport type UseMembersResult = Pick<\n GeekappsAuthContextValue,\n | \"listMembers\"\n | \"getMember\"\n | \"addMember\"\n | \"updateMember\"\n | \"updateMemberRole\"\n | \"removeMember\"\n | \"inviteMember\"\n | \"listInvites\"\n | \"revokeInvite\"\n>;\n\nexport type UsePublicOrganizationsResult = Pick<GeekappsAuthContextValue, \"listPublicOrganizations\">;\n\nexport type UseJoinRequestsResult = Pick<\n GeekappsAuthContextValue,\n | \"requestToJoin\"\n | \"getMyJoinRequest\"\n | \"cancelJoinRequest\"\n | \"listJoinRequests\"\n | \"approveJoinRequest\"\n | \"rejectJoinRequest\"\n>;\n\nexport type UseInvitesResult = Pick<\n GeekappsAuthContextValue,\n \"getInvitePreview\" | \"acceptInvite\" | \"rejectInvite\" | \"listMyInvites\" | \"acceptInviteById\" | \"rejectInviteById\"\n>;\n\nconst GeekappsAuthContext = createContext<GeekappsAuthContextValue | null>(null);\n\nexport function GeekappsAuthProvider({\n children,\n basePath = \"/api/auth\",\n initialUser = null,\n initialOrganizations = [],\n initialCurrentOrgId = null,\n}: GeekappsAuthProviderProps): ReactElement {\n const [user, setUser] = useState<User | null>(initialUser);\n const [isLoading, setIsLoading] = useState(true);\n const [accounts, setAccounts] = useState<ConnectedAccount[]>([]);\n const [isLoadingAccounts, setIsLoadingAccounts] = useState(true);\n const [organizations, setOrganizations] = useState<Organization[]>(initialOrganizations);\n const [currentOrgId, setCurrentOrgId] = useState<string | null>(initialCurrentOrgId);\n const [isLoadingOrganizations, setIsLoadingOrganizations] = useState(true);\n\n // As chamadas de role resolvem a organização ativa na hora em que rodam, não\n // na hora em que foram criadas — sem o ref, um callback memoizado ficaria com\n // o org id que existia na primeira render.\n const currentOrgIdRef = useRef(currentOrgId);\n currentOrgIdRef.current = currentOrgId;\n\n const request = useCallback(\n async <T,>(path: string, options: RequestOptions = {}) => {\n const response = await fetch(buildUrl(basePath, path), {\n method: options.method ?? \"GET\",\n credentials: \"include\",\n headers:\n options.body === undefined\n ? undefined\n : {\n \"content-type\": \"application/json\",\n },\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n });\n\n if (response.status === 401) {\n // O servidor já limpou os cookies: a sessão expirou ou foi revogada no\n // painel. Zera o estado local para a interface parar de mostrar\n // alguém logado, e lança um erro reconhecível em vez de \"401\".\n setUser(null);\n setAccounts([]);\n throw new GeekappsSessionExpiredError();\n }\n\n if (!response.ok) {\n const data = await response.clone().json().catch(() => null);\n throw new GeekappsApiError(\n await parseError(response),\n response.status,\n typeof data?.code === \"string\" ? data.code : undefined,\n Array.isArray(data?.missingFields) ? data.missingFields : undefined,\n );\n }\n\n if (response.status === 204) {\n return null as T;\n }\n\n return (await response.json()) as T;\n },\n [basePath],\n );\n\n const refreshUser = useCallback(async () => {\n setIsLoading(true);\n try {\n const { user: u } = await request<{ user: User | null }>(\"/me\");\n setUser(u);\n } catch {\n setUser(null);\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const refreshAccounts = useCallback(async () => {\n setIsLoadingAccounts(true);\n try {\n const { accounts: a } = await request<{ accounts: ConnectedAccount[] }>(\n \"/accounts\",\n );\n setAccounts(a);\n } catch {\n setAccounts([]);\n } finally {\n setIsLoadingAccounts(false);\n }\n }, []);\n\n const refreshOrganizations = useCallback(async () => {\n setIsLoadingOrganizations(true);\n try {\n const { organizations: orgs, currentOrgId: nextCurrentOrgId } =\n await request<{\n organizations: Organization[];\n currentOrgId?: string | null;\n }>(\"/organizations\");\n setOrganizations(orgs);\n setCurrentOrgId((current) => {\n if (nextCurrentOrgId !== undefined) return nextCurrentOrgId ?? null;\n if (current && orgs.some((org) => org.id === current)) return current;\n return orgs[0]?.id ?? null;\n });\n } catch {\n setOrganizations([]);\n setCurrentOrgId(null);\n } finally {\n setIsLoadingOrganizations(false);\n }\n }, []);\n\n useEffect(() => {\n void refreshUser();\n void refreshAccounts();\n void refreshOrganizations();\n }, [refreshAccounts, refreshOrganizations, refreshUser]);\n\n const currentOrg = useMemo(\n () => organizations.find((organization) => organization.id === currentOrgId) ?? null,\n [currentOrgId, organizations],\n );\n\n const [currentMembership, setCurrentMembership] = useState<OrganizationMembership | null>(null);\n const [isLoadingMembership, setIsLoadingMembership] = useState(false);\n\n const getMyMembership = useCallback(\n async (organizationId?: string) => {\n const orgId = organizationId ?? currentOrgId;\n if (!orgId) return null;\n try {\n return await request<OrganizationMembership>(\n `/organizations/${encodeURIComponent(orgId)}/members/me`,\n );\n } catch {\n return null;\n }\n },\n [currentOrgId, request],\n );\n\n const refreshMembership = useCallback(async () => {\n if (!currentOrgId || !user) {\n setCurrentMembership(null);\n return;\n }\n setIsLoadingMembership(true);\n try {\n setCurrentMembership(await getMyMembership(currentOrgId));\n } finally {\n setIsLoadingMembership(false);\n }\n }, [currentOrgId, getMyMembership, user]);\n\n useEffect(() => {\n void refreshMembership();\n }, [refreshMembership]);\n\n const setCurrentOrg = useCallback(\n async (organizationId: string | null) => {\n await request(\"/organizations/active\", {\n method: \"POST\",\n body: { organizationId },\n });\n setCurrentOrgId(organizationId);\n },\n [request],\n );\n\n const signIn = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/sign-in\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n if (options?.authorizationFlowId) url.searchParams.set(\"flow_id\", options.authorizationFlowId);\n const prompt = options?.prompt ?? (options?.silentLogin === false ? \"login\" : undefined);\n if (prompt) url.searchParams.set(\"prompt\", prompt);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const signUp = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/sign-up\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n if (options?.authorizationFlowId) url.searchParams.set(\"flow_id\", options.authorizationFlowId);\n const prompt = options?.prompt ?? (options?.silentLogin === false ? \"login\" : undefined);\n if (prompt) url.searchParams.set(\"prompt\", prompt);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const addAccount = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/add-account\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const signOut = useCallback(async () => {\n await request(\"/sign-out\", { method: \"POST\" });\n setUser(null);\n await refreshAccounts();\n }, [refreshAccounts, request]);\n\n const signOutAll = useCallback(async () => {\n await request(\"/sign-out-all\", { method: \"POST\" });\n setUser(null);\n setAccounts([]);\n }, [request]);\n\n const switchAccount = useCallback(\n async (sessionId: string, options?: SignInOptions) => {\n await request(\"/accounts/switch\", {\n method: \"POST\",\n body: { sessionId },\n });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (options?.redirectTo) redirectTo(options.redirectTo);\n },\n [refreshAccounts, refreshOrganizations, refreshUser, request],\n );\n\n async function toAuthResult<T>(fn: () => Promise<T>): Promise<AuthResult<T>> {\n try {\n return { success: true, data: await fn() };\n } catch (error) {\n if (error instanceof GeekappsApiError) {\n return {\n success: false,\n error: error.message,\n status: error.status,\n code: error.code,\n missingFields: error.missingFields,\n };\n }\n return { success: false, error: error instanceof Error ? error.message : \"Unexpected error\" };\n }\n }\n\n // ── Invites: precisam do status HTTP cru (401/404/409), não só uma\n // mensagem — request()/toAuthResult() não bastam aqui.\n const getInvitePreview = useCallback(\n (token: string) => request<OrganizationInvitePreview>(`/organizations/invites/${encodeURIComponent(token)}`),\n [request],\n );\n\n const acceptInvite = useCallback(\n async (token: string): Promise<AcceptInviteResult> => {\n const response = await fetch(buildUrl(basePath, \"/organizations/invites/accept\"), {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ token }),\n });\n const data = await response.json().catch(() => null);\n\n if (response.ok && data) {\n return {\n success: true,\n organizationId: data.organizationId,\n organizationName: data.organizationName,\n websiteUrl: data.websiteUrl ?? null,\n };\n }\n if (response.status === 409 && data?.error === \"wrong_account\") {\n return {\n success: false,\n wrongAccount: true,\n currentEmail: String(data.currentEmail ?? \"\"),\n invitedEmail: String(data.invitedEmail ?? \"\"),\n };\n }\n if (response.status === 401 && data?.error === \"login_required\") {\n return { success: false, wrongAccount: false, loginRequired: true };\n }\n return {\n success: false,\n wrongAccount: false,\n loginRequired: false,\n error: typeof data?.error === \"string\" ? data.error : `HTTP ${response.status}`,\n };\n },\n [basePath],\n );\n\n const rejectInvite = useCallback(\n async (token: string): Promise<{ success: true } | { success: false; error: string }> => {\n const response = await fetch(buildUrl(basePath, \"/organizations/invites/reject\"), {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ token }),\n });\n if (response.ok) return { success: true };\n const data = await response.json().catch(() => null);\n return { success: false, error: typeof data?.error === \"string\" ? data.error : `HTTP ${response.status}` };\n },\n [basePath],\n );\n\n const getMyJoinRequest = useCallback(\n async (organizationId: string): Promise<OrganizationJoinRequest | null> => {\n const response = await fetch(buildUrl(basePath, `/organizations/${organizationId}/join-requests/me`), {\n credentials: \"include\",\n });\n if (response.status === 404) return null;\n if (!response.ok) throw new Error(await parseError(response));\n return response.json();\n },\n [basePath],\n );\n\n const value = useMemo<GeekappsAuthContextValue>(\n () => ({\n basePath,\n user,\n isAuthenticated: !isLoading && user !== null,\n isLoading,\n accounts,\n isLoadingAccounts,\n organizations,\n currentOrg,\n currentOrgId,\n currentMembership,\n isLoadingMembership,\n getMyMembership,\n refreshMembership,\n isLoadingOrganizations,\n request,\n signIn,\n signUp,\n addAccount,\n signOut,\n signOutAll,\n refreshUser,\n refreshAccounts,\n switchAccount,\n loginWithPassword: (params) =>\n toAuthResult(async () => {\n const data = await request<LoginResponse>(\"/login/password\", { method: \"POST\", body: params });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (params.redirectTo ?? data.redirectTo) redirectTo(params.redirectTo ?? data.redirectTo!);\n return data;\n }),\n registerWithPassword: (params) =>\n toAuthResult(async () => {\n const data = await request<RegisterResponse>(\"/register/password\", { method: \"POST\", body: params });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (params.redirectTo) redirectTo(params.redirectTo);\n return data;\n }),\n startGoogleLogin: (params) => {\n const url = new URL(buildUrl(basePath, \"/login/google\"), window.location.origin);\n if (params?.callbackUrl) url.searchParams.set(\"callbackUrl\", params.callbackUrl);\n if (params?.redirectTo) url.searchParams.set(\"redirectTo\", params.redirectTo);\n if (params?.authorizationFlowId) url.searchParams.set(\"flow_id\", params.authorizationFlowId);\n redirectTo(url.toString());\n },\n requestPasswordlessLink: (params) =>\n toAuthResult(() => request(\"/passwordless/link\", { method: \"POST\", body: params })),\n refreshOrganizations,\n setCurrentOrg,\n createOrganization: (input) =>\n toAuthResult(async () => {\n const organization = await request<Organization>(\"/organizations\", { method: \"POST\", body: input });\n await refreshOrganizations();\n setCurrentOrgId(organization.id);\n return organization;\n }),\n lookupTaxId: (value, type = \"br_cnpj\") =>\n toAuthResult(() =>\n request<TaxIdLookupResult>(\n `/organizations/tax-id/lookup?type=${encodeURIComponent(type)}&value=${encodeURIComponent(value)}`,\n ),\n ),\n updateOrganization: (id, input) =>\n toAuthResult(async () => {\n const organization = await request<Organization>(`/organizations/${id}`, { method: \"PATCH\", body: input });\n await refreshOrganizations();\n return organization;\n }),\n deleteOrganization: (id) =>\n toAuthResult(async () => {\n await request<null>(`/organizations/${id}`, { method: \"DELETE\" });\n await refreshOrganizations();\n return null;\n }),\n hasPermission: async (options) => {\n try {\n const data = await request<{ allowed: boolean }>(\"/permissions/check\", {\n method: \"POST\",\n body: options,\n });\n return data.allowed;\n } catch {\n return false;\n }\n },\n listUsers: (params) => {\n const query = new URLSearchParams();\n if (params?.organizationId) query.set(\"organizationId\", params.organizationId);\n return request<User[]>(`/users${query.size ? `?${query.toString()}` : \"\"}`);\n },\n getUser: (id) => request<User>(`/users/${id}`),\n createUser: (input) => toAuthResult(() => request<User>(\"/users\", { method: \"POST\", body: input })),\n updateUser: (id, input) => toAuthResult(() => request<User>(`/users/${id}`, { method: \"PATCH\", body: input })),\n deleteUser: (id) =>\n toAuthResult(async () => {\n await request<null>(`/users/${id}`, { method: \"DELETE\" });\n return null;\n }),\n // Roles são sempre resolvidas no escopo de uma organização — o\n // auth-server não expõe /roles solto. Sem organizationId explícito,\n // usa a organização ativa; sem nenhuma das duas não há o que consultar.\n listRoles: async (params) => {\n const organizationId = params?.organizationId ?? currentOrgIdRef.current;\n if (!organizationId) {\n throw new Error(\n \"listRoles: informe organizationId — não há organização ativa para resolver as roles.\",\n );\n }\n const roles = await request<Role[]>(`/organizations/${organizationId}/roles`);\n // O endpoint devolve a lista inteira; a separação system/custom é\n // feita aqui para manter o contrato que os consumidores já usam.\n return {\n systemRoles: roles.filter((role) => role.isDefault),\n customRoles: roles.filter((role) => !role.isDefault),\n };\n },\n getRole: (id, _type, organizationId) => {\n const orgId = organizationId ?? currentOrgIdRef.current;\n if (!orgId) {\n throw new Error(\"getRole: informe organizationId — não há organização ativa.\");\n }\n return request<Role>(`/organizations/${orgId}/roles/${id}`);\n },\n createRole: ({ organizationId, permissionDefinitionIds, applicationId: _applicationId, ...rest }) =>\n toAuthResult(() => {\n const orgId = organizationId ?? currentOrgIdRef.current;\n if (!orgId) {\n throw new Error(\"createRole: informe organizationId — não há organização ativa.\");\n }\n return request<Role>(`/organizations/${orgId}/roles`, {\n method: \"POST\",\n // O auth-server espera permissionIds; permissionDefinitionIds é o\n // nome herdado no SDK.\n body: { ...rest, permissionIds: permissionDefinitionIds ?? [] },\n });\n }),\n updateRole: (id, { permissionDefinitionIds, ...rest }, organizationId) =>\n toAuthResult(() => {\n const orgId = organizationId ?? currentOrgIdRef.current;\n if (!orgId) {\n throw new Error(\"updateRole: informe organizationId — não há organização ativa.\");\n }\n return request<Role>(`/organizations/${orgId}/roles/${id}`, {\n method: \"PATCH\",\n body: {\n ...rest,\n ...(permissionDefinitionIds ? { permissionIds: permissionDefinitionIds } : {}),\n },\n });\n }),\n deleteRole: (id, organizationId) =>\n toAuthResult(async () => {\n const orgId = organizationId ?? currentOrgIdRef.current;\n if (!orgId) {\n throw new Error(\"deleteRole: informe organizationId — não há organização ativa.\");\n }\n await request<null>(`/organizations/${orgId}/roles/${id}`, { method: \"DELETE\" });\n return null;\n }),\n listPermissions: (params) => {\n const query = new URLSearchParams();\n if (params?.applicationId) query.set(\"applicationId\", params.applicationId);\n if (params?.roleId) query.set(\"roleId\", params.roleId);\n return request<Permission[]>(`/permissions${query.size ? `?${query.toString()}` : \"\"}`);\n },\n createPermission: (input) =>\n toAuthResult(() => request<Permission>(\"/permissions\", { method: \"POST\", body: input })),\n updatePermission: (id, input) =>\n toAuthResult(() => request<Permission>(`/permissions/${id}`, { method: \"PATCH\", body: input })),\n deletePermission: (id) =>\n toAuthResult(async () => {\n await request<null>(`/permissions/${id}`, { method: \"DELETE\" });\n return null;\n }),\n listUserSessions: (params) => {\n const query = new URLSearchParams();\n if (params?.userId) query.set(\"userId\", params.userId);\n if (params?.organizationId) query.set(\"organizationId\", params.organizationId);\n return request<UserSession[]>(`/sessions${query.size ? `?${query.toString()}` : \"\"}`);\n },\n revokeUserSession: (sessionId) =>\n toAuthResult(async () => {\n await request<null>(`/sessions/${sessionId}`, { method: \"DELETE\" });\n return null;\n }),\n listMembers: (organizationId) =>\n request<OrganizationMember[]>(`/organizations/${organizationId}/members`),\n getMember: (organizationId, memberId) =>\n request<OrganizationMember>(`/organizations/${organizationId}/members/${memberId}`),\n addMember: (organizationId, input) =>\n toAuthResult(() =>\n request<OrganizationMember>(`/organizations/${organizationId}/members`, {\n method: \"POST\",\n body: input,\n }),\n ),\n updateMember: (organizationId, memberId, input) =>\n toAuthResult(() =>\n request<OrganizationMember>(`/organizations/${organizationId}/members/${memberId}`, {\n method: \"PATCH\",\n body: input,\n }),\n ),\n updateMemberRole: (organizationId, memberId, input) =>\n toAuthResult(() =>\n request<OrganizationMember>(`/organizations/${organizationId}/members/${memberId}`, {\n method: \"PATCH\",\n body: input,\n }),\n ),\n removeMember: (organizationId, memberId) =>\n toAuthResult(async () => {\n await request<null>(`/organizations/${organizationId}/members/${memberId}`, { method: \"DELETE\" });\n return null;\n }),\n inviteMember: (organizationId, input) =>\n toAuthResult(() =>\n request<OrganizationInvite>(`/organizations/${organizationId}/invites`, {\n method: \"POST\",\n body: input,\n }),\n ),\n listInvites: (organizationId) =>\n request<OrganizationInvite[]>(`/organizations/${organizationId}/invites`),\n revokeInvite: (organizationId, inviteId) =>\n toAuthResult(async () => {\n await request<null>(`/organizations/${organizationId}/invites/${inviteId}`, { method: \"DELETE\" });\n return null;\n }),\n listPublicOrganizations: () => request<PublicOrganization[]>(\"/organizations/public\"),\n requestToJoin: (organizationId, input) =>\n toAuthResult(() =>\n request<OrganizationJoinRequest>(`/organizations/${organizationId}/join-requests`, {\n method: \"POST\",\n body: input ?? {},\n }),\n ),\n getMyJoinRequest,\n cancelJoinRequest: (organizationId) =>\n toAuthResult(async () => {\n await request<null>(`/organizations/${organizationId}/join-requests/me`, { method: \"DELETE\" });\n return null;\n }),\n listJoinRequests: (organizationId) =>\n request<OrganizationJoinRequest[]>(`/organizations/${organizationId}/join-requests`),\n approveJoinRequest: (organizationId, requestId) =>\n toAuthResult(() =>\n request<OrganizationJoinRequest>(`/organizations/${organizationId}/join-requests/${requestId}/approve`, {\n method: \"POST\",\n }),\n ),\n rejectJoinRequest: (organizationId, requestId) =>\n toAuthResult(() =>\n request<OrganizationJoinRequest>(`/organizations/${organizationId}/join-requests/${requestId}/reject`, {\n method: \"POST\",\n }),\n ),\n getInvitePreview,\n acceptInvite,\n rejectInvite,\n listMyInvites: () => request<MyOrganizationInvite[]>(\"/me/invites\"),\n acceptInviteById: async (inviteId) => {\n const result = await request<{ success: true; organizationId: string; organizationName: string }>(\n `/me/invites/${encodeURIComponent(inviteId)}/accept`,\n { method: \"POST\" },\n );\n await refreshOrganizations();\n return result;\n },\n rejectInviteById: async (inviteId) => {\n await request(`/me/invites/${encodeURIComponent(inviteId)}/reject`, { method: \"POST\" });\n },\n }),\n [\n accounts,\n acceptInvite,\n addAccount,\n basePath,\n currentOrg,\n currentOrgId,\n currentMembership,\n isLoadingMembership,\n getMyMembership,\n refreshMembership,\n getInvitePreview,\n getMyJoinRequest,\n isLoading,\n isLoadingAccounts,\n isLoadingOrganizations,\n organizations,\n refreshAccounts,\n refreshOrganizations,\n refreshUser,\n rejectInvite,\n request,\n setCurrentOrg,\n signIn,\n signOut,\n signOutAll,\n signUp,\n switchAccount,\n user,\n ],\n );\n\n return <GeekappsAuthContext.Provider value={value}>{children}</GeekappsAuthContext.Provider>;\n}\n\nexport function useAuth(): GeekappsAuthContextValue {\n const context = useContext(GeekappsAuthContext);\n if (!context) throw new Error(\"useAuth must be used inside GeekappsAuthProvider\");\n return context;\n}\n\nexport function useOrg(): UseOrgResult {\n const context = useAuth();\n return {\n organizations: context.organizations,\n currentOrg: context.currentOrg,\n currentOrgId: context.currentOrgId,\n isLoadingOrganizations: context.isLoadingOrganizations,\n refreshOrganizations: context.refreshOrganizations,\n setCurrentOrg: context.setCurrentOrg,\n createOrganization: context.createOrganization,\n lookupTaxId: context.lookupTaxId,\n updateOrganization: context.updateOrganization,\n deleteOrganization: context.deleteOrganization,\n hasPermission: context.hasPermission,\n currentMembership: context.currentMembership,\n isLoadingMembership: context.isLoadingMembership,\n getMyMembership: context.getMyMembership,\n refreshMembership: context.refreshMembership,\n };\n}\n\nexport function useAccounts(): UseAccountsResult {\n const context = useAuth();\n return {\n accounts: context.accounts,\n addAccount: context.addAccount,\n isLoadingAccounts: context.isLoadingAccounts,\n refreshAccounts: context.refreshAccounts,\n switchAccount: context.switchAccount,\n };\n}\n\nexport function useUsers(): UseUsersResult {\n const context = useAuth();\n return {\n listUsers: context.listUsers,\n getUser: context.getUser,\n createUser: context.createUser,\n updateUser: context.updateUser,\n deleteUser: context.deleteUser,\n };\n}\n\nexport function useRoles(): UseRolesResult {\n const context = useAuth();\n return {\n listRoles: context.listRoles,\n getRole: context.getRole,\n createRole: context.createRole,\n updateRole: context.updateRole,\n deleteRole: context.deleteRole,\n };\n}\n\nexport function usePermissions(): UsePermissionsResult {\n const context = useAuth();\n return {\n listPermissions: context.listPermissions,\n createPermission: context.createPermission,\n updatePermission: context.updatePermission,\n deletePermission: context.deletePermission,\n };\n}\n\nexport function useSessions(): UseSessionsResult {\n const context = useAuth();\n return {\n listUserSessions: context.listUserSessions,\n revokeUserSession: context.revokeUserSession,\n };\n}\n\nexport function useMembers(): UseMembersResult {\n const context = useAuth();\n return {\n listMembers: context.listMembers,\n getMember: context.getMember,\n addMember: context.addMember,\n updateMember: context.updateMember,\n updateMemberRole: context.updateMemberRole,\n removeMember: context.removeMember,\n inviteMember: context.inviteMember,\n listInvites: context.listInvites,\n revokeInvite: context.revokeInvite,\n };\n}\n\n/**\n * Descoberta de organizações PÚBLICAS do app — bem separado de `useOrg()`,\n * que lida com as organizações do próprio usuário (as que ele já é\n * membro/dono). `usePublicOrganizations()` nunca retorna organizações\n * privadas, e não exige que o usuário já pertença a elas.\n */\nexport function usePublicOrganizations(): UsePublicOrganizationsResult {\n const context = useAuth();\n return {\n listPublicOrganizations: context.listPublicOrganizations,\n };\n}\n\n/**\n * Solicitações de entrada em organizações públicas: um usuário pede pra\n * entrar (requestToJoin) e um admin da organização aprova/rejeita\n * (approveJoinRequest/rejectJoinRequest, exigem permissão org:members:add).\n */\nexport function useJoinRequests(): UseJoinRequestsResult {\n const context = useAuth();\n return {\n requestToJoin: context.requestToJoin,\n getMyJoinRequest: context.getMyJoinRequest,\n cancelJoinRequest: context.cancelJoinRequest,\n listJoinRequests: context.listJoinRequests,\n approveJoinRequest: context.approveJoinRequest,\n rejectJoinRequest: context.rejectJoinRequest,\n };\n}\n\n/**\n * Aceite/recusa de convite por email — chamadas a partir do ?invite_token=\n * que este app recebe na sua própria redirectUri (a que foi passada em\n * useMembers().inviteMember). getInvitePreview funciona sem sessão\n * (currentAccount vem null); rejectInvite não exige login; acceptInvite\n * retorna loginRequired:true se não houver sessão.\n */\nexport function useInvites(): UseInvitesResult {\n const context = useAuth();\n return {\n getInvitePreview: context.getInvitePreview,\n acceptInvite: context.acceptInvite,\n rejectInvite: context.rejectInvite,\n listMyInvites: context.listMyInvites,\n acceptInviteById: context.acceptInviteById,\n rejectInviteById: context.rejectInviteById,\n };\n}\n\n// ── Service Accounts ─────────────────────────────────────────────────────────\n\nexport type ServiceAccount = {\n id: string;\n membershipId: string;\n organizationId: string;\n applicationId: string | null;\n name: string;\n status: \"active\" | \"inactive\" | \"suspended\";\n serviceId: string | null;\n roleAssignment: { role: { id: string; key: string; name: string } } | null;\n createdAt: string;\n updatedAt: string;\n};\n\nexport type ServiceAccountWithSecret = ServiceAccount & { serviceSecret: string };\n\nexport type CreateServiceAccountInput = {\n organizationId: string;\n applicationId?: string;\n name: string;\n description?: string;\n roleId?: string;\n};\n\nexport type UseServiceAccountResult = {\n listServiceAccounts: (params: { organizationId: string; applicationId?: string }) => Promise<ServiceAccount[]>;\n createServiceAccount: (input: CreateServiceAccountInput) => Promise<ServiceAccountWithSecret>;\n updateServiceAccountRole: (id: string, roleId: string | null) => Promise<void>;\n revokeServiceAccount: (id: string) => Promise<void>;\n rotateServiceAccountSecret: (id: string) => Promise<{ serviceId: string; serviceSecret: string }>;\n deleteServiceAccount: (id: string) => Promise<void>;\n};\n\nexport function useServiceAccount(): UseServiceAccountResult {\n const { request } = useAuth();\n\n const listServiceAccounts = useCallback(\n (params: { organizationId: string; applicationId?: string }) => {\n const query = new URLSearchParams({ organizationId: params.organizationId });\n if (params.applicationId) query.set(\"applicationId\", params.applicationId);\n return request<ServiceAccount[]>(`/service-accounts?${query.toString()}`);\n },\n [request],\n );\n\n const createServiceAccount = useCallback(\n (input: CreateServiceAccountInput) =>\n request<ServiceAccountWithSecret>(\"/service-accounts\", { method: \"POST\", body: input }),\n [request],\n );\n\n const updateServiceAccountRole = useCallback(\n async (id: string, roleId: string | null) => {\n await request<void>(`/service-accounts/${id}`, { method: \"PATCH\", body: { roleId } });\n },\n [request],\n );\n\n const revokeServiceAccount = useCallback(\n async (id: string) => {\n await request<void>(`/service-accounts/${id}/revoke`, { method: \"POST\" });\n },\n [request],\n );\n\n const rotateServiceAccountSecret = useCallback(\n (id: string) =>\n request<{ serviceId: string; serviceSecret: string }>(`/service-accounts/${id}/rotate-secret`, {\n method: \"POST\",\n }),\n [request],\n );\n\n const deleteServiceAccount = useCallback(\n async (id: string) => {\n await request<null>(`/service-accounts/${id}`, { method: \"DELETE\" });\n },\n [request],\n );\n\n return {\n listServiceAccounts,\n createServiceAccount,\n updateServiceAccountRole,\n revokeServiceAccount,\n rotateServiceAccountSecret,\n deleteServiceAccount,\n };\n}\n"],"mappings":"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","names":["value"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n createContext,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\n/**\n * A sessão não vale mais: expirou ou foi revogada. O estado local já foi\n * limpo quando este erro é lançado — o tratamento normal é levar ao login.\n */\nexport class GeekappsSessionExpiredError extends Error {\n readonly code = \"session_expired\" as const;\n\n constructor(message = \"A sessão expirou ou foi revogada. Entre novamente.\") {\n super(message);\n this.name = \"GeekappsSessionExpiredError\";\n }\n}\n\nexport type UserStatus = \"active\" | \"inactive\" | \"suspended\";\nexport type OrganizationStatus = \"active\" | \"inactive\" | \"suspended\";\nexport type OAuthClientType = \"public\" | \"confidential\";\n\n/**\n * Códigos de erro conhecidos devolvidos pelo auth-server. A lista é aberta\n * (`string & {}`): códigos novos continuam tipados como string.\n */\nexport type AuthErrorCode =\n | \"waitlist_required\"\n | \"waitlist_disabled\"\n | \"password_reset_required\"\n | \"account_locked\"\n | \"invalid_credentials\"\n | \"not_found\"\n | \"invalid_request\"\n | \"interaction_required\"\n | (string & {});\n\nexport type AuthResult<T = unknown> =\n | { success: true; data: T }\n | {\n success: false;\n error: string;\n status?: number;\n /** Código de erro da API (ex.: \"waitlist_required\", \"account_locked\", \"legal_fields_required\"). */\n code?: AuthErrorCode;\n /** Segundos até poder tentar de novo (`account_locked`). */\n retryAfter?: number;\n /** Campos obrigatórios que faltaram (ex.: \"legalName\", \"legalAddress.city\"). */\n missingFields?: string[];\n };\n\n/** Erro de request com o corpo estruturado da API (code/missingFields). */\nexport class GeekappsApiError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly code?: string,\n readonly missingFields?: string[],\n readonly retryAfter?: number,\n ) {\n super(message);\n this.name = \"GeekappsApiError\";\n }\n}\n\n/** standard: organização comum. legal: pessoa jurídica associada a um Tax ID (CNPJ ou genérico). */\nexport type OrganizationType = \"standard\" | \"legal\";\nexport type TaxIdType = \"br_cnpj\" | \"generic\";\n\nexport type OrganizationLegalAddress = {\n street?: string | null;\n number?: string | null;\n complement?: string | null;\n district?: string | null;\n city?: string | null;\n state?: string | null;\n postalCode?: string | null;\n /** ISO 3166-1 alpha-2 */\n country?: string | null;\n};\n\nexport type OrganizationLegalData = {\n legalName: string | null;\n tradeName: string | null;\n legalEmail: string | null;\n legalPhone: string | null;\n legalAddress: OrganizationLegalAddress | null;\n};\n\nexport type TaxIdLookupResult = {\n taxId: string;\n taxIdType: TaxIdType;\n taxIdCountry: string | null;\n valid: boolean;\n /** Já existe uma organização deste app com esse Tax ID. */\n alreadyRegistered: boolean;\n /** false quando a fonte pública estava indisponível — preencha manualmente. */\n lookupAvailable: boolean;\n found: boolean;\n registrationStatus: string | null;\n suggestedName: string | null;\n data: OrganizationLegalData;\n /** Obrigatórios que a consulta não conseguiu preencher — peça ao usuário. */\n missingFields: string[];\n};\n\nexport type User = {\n id: string;\n email: string;\n name: string | null;\n phone: string | null;\n imageUrl: string | null;\n status?: UserStatus;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type ConnectedAccount = {\n id: string;\n sessionId?: string;\n isActive: boolean;\n user: User;\n};\n\nexport type Permission = {\n id: string;\n applicationId?: string | null;\n key: string;\n name: string;\n description: string | null;\n category: string | null;\n isSystem: boolean;\n isActive: boolean;\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type RolePermission = {\n permissionDefinition: Permission;\n};\n\nexport type Role = {\n id: string;\n applicationId?: string | null;\n /** Present only on custom roles */\n organizationId?: string | null;\n /** \"system\" | \"custom\" */\n type?: string;\n key: string;\n name: string;\n description: string | null;\n isSystem?: boolean;\n isDefault?: boolean;\n isActive: boolean;\n permissions: RolePermission[];\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type RoleAssignment = {\n id: string;\n roleDefinitionId?: string | null;\n customRoleId?: string | null;\n roleDefinition?: Role | null;\n customRole?: Role | null;\n};\n\n/** Role de um membro, como o auth-server devolve. */\nexport type MemberRole = {\n id: string;\n key: string;\n name: string;\n isDefault: boolean;\n isActive: boolean;\n};\n\n/** Convite recebido pelo usuário logado (GET /me/invites). Nunca traz o token do e-mail. */\nexport type MyOrganizationInvite = {\n id: string;\n organizationId: string;\n email: string;\n status: \"pending\";\n expiresAt: string;\n createdAt: string;\n role: { id: string; key: string; name: string } | null;\n organization: { id: string; name: string; slug: string; imageUrl: string | null; applicationId: string };\n};\n\nexport type OrganizationMember = {\n id: string;\n organizationId?: string;\n userId?: string;\n status?: OrganizationStatus;\n createdAt?: string | Date;\n user: User;\n /** Role do membro na organização (null = sem role atribuída). */\n role?: MemberRole | null;\n /** @deprecated formato antigo — o auth-server devolve `role`. */\n roleAssignments?: RoleAssignment[];\n};\n\n/** Participação do usuário logado numa organização (GET /organizations/:id/members/me). */\nexport type OrganizationMembership = {\n organizationId: string;\n membershipId: string | null;\n status: OrganizationStatus;\n /** Dono da organização: passa em qualquer checagem de permissão. */\n isOwner: boolean;\n role: MemberRole | null;\n /** Permissões efetivas da role (keys). Para o dono, use `isOwner`. */\n permissions: string[];\n joinedAt: string | Date | null;\n};\n\nexport type OrganizationInvite = {\n id: string;\n organizationId: string;\n email: string;\n /**\n * Role que o convidado assume ao aceitar. Vem aninhada do auth-server (não\n * como roleId solto) — null quando o convite não fixa nenhuma e o membro\n * cai na role default da organização.\n */\n role: { id: string; key: string; name: string } | null;\n /** @deprecated use `role.id` — o auth-server não devolve este campo. */\n roleId?: string | null;\n status: \"pending\" | \"accepted\" | \"expired\" | \"revoked\";\n expiresAt: string | Date;\n acceptedAt?: string | Date | null;\n createdAt?: string | Date;\n redirectUri?: string | null;\n emailTitle?: string | null;\n emailSubtitle?: string | null;\n emailMessage?: string | null;\n};\n\nexport type MemberInviteInput = {\n email: string;\n roleId?: string;\n /**\n * URI pra onde o link do e-mail manda o usuário — precisa estar cadastrada\n * em Application.redirectUris (mesma validação do /authorize). Este app\n * deve expor uma rota nessa URI que trata o `?invite_token=` anexado (ver\n * useJoinRequests/inviteApi.preview|accept|reject abaixo).\n */\n redirectUri: string;\n emailTitle?: string;\n emailSubtitle?: string;\n emailMessage?: string;\n};\n\nexport type AddMemberInput = {\n userId: string;\n roleId?: string;\n};\n\nexport type UpdateMemberInput = {\n status?: \"active\" | \"inactive\" | \"suspended\";\n roleId?: string | null;\n};\n\n/** @deprecated use UpdateMemberInput */\nexport type UpdateMemberRoleInput = {\n roleId: string;\n};\n\nexport type PublicOrganization = {\n id: string;\n name: string;\n slug: string;\n description: string | null;\n imageUrl: string | null;\n createdAt: string | Date;\n};\n\nexport type OrganizationInvitePreview =\n | {\n alreadyAccepted: true;\n organizationId: string;\n organizationName: string;\n applicationName: string;\n applicationImageUrl: string | null;\n applicationImageFileId: string | null;\n organizationImageUrl: string | null;\n organizationImageFileId: string | null;\n websiteUrl: string | null;\n }\n | {\n alreadyAccepted?: false;\n email: string;\n organizationId: string;\n organizationName: string;\n applicationName: string;\n applicationId: string;\n applicationImageUrl: string | null;\n applicationImageFileId: string | null;\n organizationImageUrl: string | null;\n organizationImageFileId: string | null;\n websiteUrl: string | null;\n redirectUri: string | null;\n appStoreUrl: string | null;\n playStoreUrl: string | null;\n currentAccount: { email: string; name: string | null } | null;\n };\n\nexport type AcceptInviteResult =\n | { success: true; organizationId: string; organizationName: string; websiteUrl: string | null }\n | { success: false; wrongAccount: true; currentEmail: string; invitedEmail: string }\n | { success: false; wrongAccount: false; loginRequired: true }\n | { success: false; wrongAccount: false; loginRequired: false; error: string };\n\nexport type JoinRequestStatus = \"pending\" | \"approved\" | \"rejected\" | \"cancelled\";\n\nexport type OrganizationJoinRequest = {\n id: string;\n organizationId: string;\n userId: string;\n status: JoinRequestStatus;\n message: string | null;\n reviewedByUserId: string | null;\n reviewedAt: string | null;\n createdAt: string | Date;\n updatedAt: string | Date;\n};\n\nexport type WaitlistEntry = {\n id: string;\n email: string;\n name: string | null;\n status: WaitlistStatus;\n position: number | null;\n createdAt: string;\n approvedAt: string | null;\n};\n\nexport type WaitlistList = { waiting: number; entries: WaitlistEntry[] };\n\nexport type ForcePasswordResetInput = {\n organizationId: string;\n applicationId: string;\n userIds?: string[];\n all?: boolean;\n};\n\nexport type ForcePasswordResetResult = {\n ok: boolean;\n scheduled: number;\n alreadyPending: number;\n skipped: number;\n estimatedMinutes: number;\n batchSize: number;\n intervalSeconds: number;\n};\n\nexport type ForcePasswordResetProgress = {\n pending: number;\n done: number;\n failed: number;\n batchSize: number;\n intervalSeconds: number;\n};\n\n/** Campos graváveis de uma Application via PATCH /applications/:id. */\nexport type ApplicationUpdateInput = {\n name?: string;\n description?: string | null;\n imageUrl?: string | null;\n /** Só e-mails aprovados na lista de espera podem se cadastrar. */\n waitlistEnabled?: boolean;\n [key: string]: unknown;\n};\n\nexport type OrganizationOwnedApplication = {\n waitlistEnabled?: boolean;\n id: string;\n name: string;\n description: string | null;\n imageUrl: string | null;\n type?: OAuthClientType;\n organizationId: string;\n isFirstParty: boolean;\n ssoEnabled: boolean;\n status?: \"active\" | \"inactive\" | \"suspended\";\n createdAt?: string | Date;\n updatedAt?: string | Date;\n};\n\nexport type Organization = {\n id: string;\n name: string;\n description: string | null;\n slug: string;\n domain: string | null;\n imageUrl: string | null;\n faviconUrl: string | null;\n status: OrganizationStatus;\n /** \"private\" (padrão) nunca sai em listPublicOrganizations(); \"public\" sai, e aceita join requests. */\n visibility?: \"public\" | \"private\";\n type?: OrganizationType;\n taxId?: string | null;\n taxIdType?: TaxIdType | null;\n taxIdCountry?: string | null;\n legalName?: string | null;\n tradeName?: string | null;\n legalEmail?: string | null;\n legalPhone?: string | null;\n legalAddress?: OrganizationLegalAddress | null;\n taxIdVerifiedAt?: string | Date | null;\n members?: OrganizationMember[];\n ownedApplications?: OrganizationOwnedApplication[];\n applicationLinks?: Array<{\n id: string;\n status: OrganizationStatus;\n createdAt?: string | Date;\n application: OrganizationOwnedApplication;\n }>;\n createdAt: string | Date;\n updatedAt: string | Date;\n};\n\nexport type SessionApplication = {\n id: string;\n createdAt: string | Date;\n expiresAt: string | Date;\n application: {\n id: string;\n name: string;\n organizationId: string;\n };\n};\n\nexport type UserSession = {\n id: string;\n userId: string;\n organizationId: string | null;\n deviceAgent: string | null;\n deviceId: string | null;\n deviceName: string | null;\n ip: string | null;\n authState?: unknown;\n authTime?: string | Date;\n expiresAt: string | Date;\n createdAt: string | Date;\n updatedAt: string | Date;\n user?: User;\n applicationSessions?: SessionApplication[];\n};\n\nexport type UserInput = {\n name?: string | null;\n email?: string;\n phone?: string | null;\n imageUrl?: string | null;\n password?: string;\n organizationId?: string | null;\n status?: UserStatus;\n};\n\nexport type OrganizationInput = {\n name: string;\n description?: string | null;\n slug: string;\n domain?: string | null;\n imageUrl?: string | null;\n faviconUrl?: string | null;\n visibility?: \"public\" | \"private\";\n /** \"legal\" exige taxId; dados da empresa (CNPJ) são buscados automaticamente no servidor. */\n type?: OrganizationType;\n taxId?: string | null;\n /** Padrão: \"br_cnpj\". */\n taxIdType?: TaxIdType | null;\n /** Obrigatório para taxIdType \"generic\". */\n taxIdCountry?: string | null;\n} & Partial<OrganizationLegalData>;\n\nexport type OrganizationUpdateInput = Partial<\n Omit<OrganizationInput, \"type\" | \"taxId\" | \"taxIdType\" | \"taxIdCountry\">\n> & {\n status?: OrganizationStatus;\n};\n\nexport type RoleInput = {\n /** Opcional: sem ele, usa a organização ativa. */\n organizationId?: string;\n applicationId?: string | null;\n key: string;\n name: string;\n description?: string | null;\n permissionDefinitionIds?: string[];\n};\n\nexport type RoleUpdateInput = {\n name?: string;\n description?: string | null;\n isActive?: boolean;\n permissionDefinitionIds?: string[];\n};\n\nexport type PermissionInput = {\n applicationId?: string | null;\n key: string;\n name: string;\n description?: string | null;\n category?: string | null;\n};\n\nexport type PermissionUpdateInput = {\n name?: string;\n description?: string | null;\n category?: string | null;\n isActive?: boolean;\n};\n\n/**\n * OIDC `prompt` values understood by the Geekapps Auth Server. These control\n * whether — and how — the IDP shows UI during `signIn()`/`signUp()`/`addAccount()`.\n *\n * - `\"login\"` — Forces the login screen, even if the user already has an active\n * session. Use this for a fresh login, unrelated to whatever session already\n * exists (equivalent to the old `silentLogin: false`).\n * - `\"select_account\"` — Shows the account picker so the user can choose among\n * their connected accounts, or add a new one. Use this when you want to let\n * the user switch accounts explicitly.\n * - `\"none\"` — Never shows any UI. The IDP authenticates silently if there is\n * exactly one active session (and no other interaction — like consent or a\n * security check — is pending); otherwise it fails immediately with an OIDC\n * error (`login_required`, `account_selection_required`, `consent_required`,\n * or `interaction_required`) instead of prompting the user. Use this for\n * silent-auth checks (e.g. \"is the user still logged in?\") where you don't\n * want to interrupt them with a screen.\n * - `\"consent\"` — Forces the consent screen even if the user already granted\n * the requested scopes before.\n *\n * Omitting `prompt` entirely runs the IDP's default flow: reuse a single\n * existing session silently, ask the user to pick when there are multiple\n * connected accounts, or show the login screen when there's none.\n */\nexport type OidcPrompt = \"login\" | \"select_account\" | \"none\" | \"consent\";\n\nexport type SignInOptions = {\n redirectTo?: string;\n authorizationFlowId?: string;\n /**\n * Controls whether the IDP shows UI, and which screen, during sign-in. See\n * {@link OidcPrompt} for what each value does. Omit it to run the default flow.\n */\n prompt?: OidcPrompt;\n /**\n * @deprecated Use `prompt: \"login\"` instead. Kept for backwards compatibility —\n * `silentLogin: false` is equivalent to `prompt: \"login\"`.\n */\n silentLogin?: boolean;\n};\n\nexport type SignInInput = SignInOptions | MouseEvent<HTMLElement>;\n\nexport type CallbackUrlOptions = SignInOptions & {\n callbackUrl?: string;\n};\n\nexport type PermissionCheckOptions = {\n permission: string;\n organizationId?: string | null;\n applicationId?: string | null;\n resourceId?: string | null;\n};\n\nexport type LoginResponse = {\n user: User;\n redirectTo?: string | null;\n};\n\nexport type RegisterResponse = User;\n\nexport type GeekappsAuthProviderProps = {\n children: ReactNode;\n basePath?: string;\n initialUser?: User | null;\n initialOrganizations?: Organization[];\n initialCurrentOrgId?: string | null;\n};\n\ntype RequestOptions = {\n body?: unknown;\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n};\n\nfunction normalizeBasePath(basePath: string) {\n return basePath.endsWith(\"/\") ? basePath.slice(0, -1) : basePath;\n}\n\nfunction buildUrl(basePath: string, path: string) {\n const normalizedPath = path.startsWith(\"/\") ? path : `/${path}`;\n return `${normalizeBasePath(basePath)}${normalizedPath}`;\n}\n\nasync function parseError(response: Response) {\n const data = await response.json().catch(() => null);\n return (\n data?.error_description ??\n data?.error ??\n data?.message ??\n `Request failed with status ${response.status}`\n );\n}\n\nasync function apiErrorFromResponse(response: Response): Promise<GeekappsApiError> {\n const data = await response.clone().json().catch(() => null);\n const code =\n typeof data?.code === \"string\" ? data.code : typeof data?.error === \"string\" ? data.error : undefined;\n const retry = Number(data?.retry_after ?? data?.retryAfter);\n return new GeekappsApiError(\n await parseError(response),\n response.status,\n code,\n Array.isArray(data?.missingFields) ? data.missingFields : undefined,\n Number.isFinite(retry) ? retry : undefined,\n );\n}\n\nfunction redirectTo(path: string) {\n window.location.assign(path);\n}\n\nfunction isMouseEvent(value: unknown): value is MouseEvent<HTMLElement> {\n return Boolean(value && typeof value === \"object\" && \"preventDefault\" in value);\n}\n\nfunction normalizeSignInOptions(input?: SignInInput): SignInOptions | undefined {\n if (!input) return undefined;\n if (isMouseEvent(input)) {\n input.preventDefault();\n return undefined;\n }\n return input;\n}\n\n\ntype ClientActionOptions = {\n basePath?: string;\n};\n\nasync function clientRequest<T>(\n path: string,\n options: RequestOptions = {},\n basePath = \"/api/auth\",\n): Promise<T> {\n const response = await fetch(buildUrl(basePath, path), {\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n credentials: \"include\",\n headers:\n options.body === undefined\n ? undefined\n : {\n \"content-type\": \"application/json\",\n },\n method: options.method ?? \"GET\",\n });\n\n if (!response.ok) {\n throw await apiErrorFromResponse(response);\n }\n\n if (response.status === 204) {\n return null as T;\n }\n\n return (await response.json()) as T;\n}\n\nasync function toStandaloneAuthResult<T>(\n fn: () => Promise<T>,\n): Promise<AuthResult<T>> {\n try {\n return {\n success: true,\n data: await fn(),\n };\n } catch (error) {\n if (error instanceof GeekappsApiError) {\n return {\n success: false,\n error: error.message,\n status: error.status,\n code: error.code,\n missingFields: error.missingFields,\n retryAfter: error.retryAfter,\n };\n }\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Auth request failed\",\n };\n }\n}\n\nexport async function loginWithPassword(\n params: {\n identifier?: string;\n email?: string;\n phone?: string;\n password: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult<LoginResponse>> {\n return toStandaloneAuthResult(async () => {\n const data = await clientRequest<LoginResponse>(\n \"/login/password\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n );\n\n if (params.redirectTo ?? data.redirectTo) {\n redirectTo(params.redirectTo ?? data.redirectTo!);\n }\n\n return data;\n });\n}\n\nexport async function registerWithPassword(\n params: {\n name: string;\n email: string;\n phone?: string;\n imageUrl?: string;\n address?: Record<string, unknown>;\n password: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult<RegisterResponse>> {\n return toStandaloneAuthResult(async () => {\n const data = await clientRequest<RegisterResponse>(\n \"/register/password\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n );\n\n if (params.redirectTo) {\n redirectTo(params.redirectTo);\n }\n\n return data;\n });\n}\n\nexport function startGoogleLogin(\n params?: CallbackUrlOptions,\n options?: ClientActionOptions,\n) {\n const basePath = options?.basePath ?? \"/api/auth\";\n const url = new URL(buildUrl(basePath, \"/login/google\"), window.location.origin);\n\n if (params?.callbackUrl) {\n url.searchParams.set(\"callbackUrl\", params.callbackUrl);\n }\n\n if (params?.redirectTo) {\n url.searchParams.set(\"redirectTo\", params.redirectTo);\n }\n\n if (params?.authorizationFlowId) {\n url.searchParams.set(\"flow_id\", params.authorizationFlowId);\n }\n\n redirectTo(url.toString());\n}\n\nexport async function requestPasswordlessLink(\n params: {\n email: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n callbackUrl?: string;\n },\n options?: ClientActionOptions,\n): Promise<AuthResult> {\n return toStandaloneAuthResult(() =>\n clientRequest(\n \"/passwordless/link\",\n {\n body: params,\n method: \"POST\",\n },\n options?.basePath,\n ),\n );\n}\n\nexport type WaitlistStatus = \"waiting\" | \"approved\" | \"joined\";\n\nexport type JoinWaitlistParams = {\n clientId: string;\n email: string;\n name?: string;\n};\n\nexport type JoinWaitlistResponse = {\n ok: true;\n status: WaitlistStatus;\n position: number | null;\n};\n\n/**\n * Entra na lista de espera de uma app com `waitlistEnabled`.\n * Erros: code \"not_found\" (404) ou \"waitlist_disabled\" (409).\n */\nexport async function joinWaitlist(\n params: JoinWaitlistParams,\n options?: ClientActionOptions,\n): Promise<AuthResult<JoinWaitlistResponse>> {\n return toStandaloneAuthResult(() =>\n clientRequest<JoinWaitlistResponse>(\n \"/waitlist/join\",\n {\n body: { client_id: params.clientId, email: params.email, name: params.name },\n method: \"POST\",\n },\n options?.basePath,\n ),\n );\n}\n\nexport type GeekappsAuthContextValue = {\n basePath: string;\n user: User | null;\n isAuthenticated: boolean;\n isLoading: boolean;\n accounts: ConnectedAccount[];\n isLoadingAccounts: boolean;\n organizations: Organization[];\n currentOrg: Organization | null;\n currentOrgId: string | null;\n isLoadingOrganizations: boolean;\n\n request: <T>(path: string, options?: RequestOptions) => Promise<T>;\n\n signIn: (options?: SignInInput) => Promise<void>;\n signUp: (options?: SignInInput) => Promise<void>;\n addAccount: (options?: SignInInput) => Promise<void>;\n signOut: () => Promise<void>;\n signOutAll: () => Promise<void>;\n refreshUser: () => Promise<void>;\n refreshAccounts: () => Promise<void>;\n switchAccount: (sessionId: string, options?: SignInOptions) => Promise<void>;\n\n loginWithPassword: (params: {\n identifier?: string;\n email?: string;\n phone?: string;\n password: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n }) => Promise<AuthResult<LoginResponse>>;\n registerWithPassword: (params: {\n name: string;\n email: string;\n phone?: string;\n imageUrl?: string;\n address?: Record<string, unknown>;\n password: string;\n redirectTo?: string;\n }) => Promise<AuthResult<RegisterResponse>>;\n startGoogleLogin: (params?: CallbackUrlOptions) => void;\n joinWaitlist: (params: JoinWaitlistParams) => Promise<AuthResult<JoinWaitlistResponse>>;\n requestPasswordlessLink: (params: {\n email: string;\n authorizationFlowId?: string;\n redirectTo?: string;\n callbackUrl?: string;\n }) => Promise<AuthResult>;\n\n refreshOrganizations: () => Promise<void>;\n setCurrentOrg: (organizationId: string | null) => Promise<void>;\n createOrganization: (input: OrganizationInput) => Promise<AuthResult<Organization>>;\n /** Valida o Tax ID e busca os dados da empresa (CNPJ) para pré-preencher a criação. */\n lookupTaxId: (value: string, type?: TaxIdType) => Promise<AuthResult<TaxIdLookupResult>>;\n updateOrganization: (id: string, input: OrganizationUpdateInput) => Promise<AuthResult<Organization>>;\n deleteOrganization: (id: string) => Promise<AuthResult<null>>;\n hasPermission: (options: PermissionCheckOptions) => Promise<boolean>;\n /** Participação do usuário na organização ativa (role, permissões, dono). Carregada sozinha ao trocar de organização. */\n currentMembership: OrganizationMembership | null;\n isLoadingMembership: boolean;\n /** Participação do usuário numa organização qualquer (padrão: a ativa). */\n getMyMembership: (organizationId?: string) => Promise<OrganizationMembership | null>;\n refreshMembership: () => Promise<void>;\n\n /** Organizações públicas e ativas deste app — nunca inclui privadas, não exige membership. Separado de `organizations` (só as do próprio usuário). */\n listPublicOrganizations: () => Promise<PublicOrganization[]>;\n\n requestToJoin: (organizationId: string, input?: { message?: string | null }) => Promise<AuthResult<OrganizationJoinRequest>>;\n getMyJoinRequest: (organizationId: string) => Promise<OrganizationJoinRequest | null>;\n cancelJoinRequest: (organizationId: string) => Promise<AuthResult<null>>;\n listJoinRequests: (organizationId: string) => Promise<OrganizationJoinRequest[]>;\n approveJoinRequest: (organizationId: string, requestId: string) => Promise<AuthResult<OrganizationJoinRequest>>;\n rejectJoinRequest: (organizationId: string, requestId: string) => Promise<AuthResult<OrganizationJoinRequest>>;\n\n /** Preview do convite por token — funciona com ou sem sessão (currentAccount vem null se deslogado). */\n getInvitePreview: (token: string) => Promise<OrganizationInvitePreview>;\n /** Aceita o convite. loginRequired:true significa que signIn() precisa rodar antes. */\n acceptInvite: (token: string) => Promise<AcceptInviteResult>;\n /** Recusa o convite — não exige estar logado. */\n rejectInvite: (token: string) => Promise<{ success: true } | { success: false; error: string }>;\n /** Convites pendentes para o e-mail do usuário logado (só deste app). */\n listMyInvites: () => Promise<MyOrganizationInvite[]>;\n /** Aceita pelo id — sem token do e-mail; só o próprio convidado consegue. */\n acceptInviteById: (inviteId: string) => Promise<{ success: true; organizationId: string; organizationName: string }>;\n /** Recusa pelo id — só o próprio convidado consegue. */\n rejectInviteById: (inviteId: string) => Promise<void>;\n\n listUsers: (params?: { organizationId?: string | null }) => Promise<User[]>;\n getUser: (id: string) => Promise<User>;\n createUser: (input: UserInput) => Promise<AuthResult<User>>;\n updateUser: (id: string, input: UserInput) => Promise<AuthResult<User>>;\n deleteUser: (id: string) => Promise<AuthResult<null>>;\n\n /**\n * Roles da organização. `organizationId` é opcional: sem ele, usa a\n * organização ativa. `applicationId`/`type` são aceitos por\n * compatibilidade e não filtram nada — a separação system/custom vem no\n * próprio retorno.\n */\n listRoles: (params?: { organizationId?: string; applicationId?: string; type?: \"system\" | \"custom\" | \"all\" }) => Promise<{ systemRoles: Role[]; customRoles: Role[] }>;\n getRole: (id: string, type?: \"system\" | \"custom\", organizationId?: string) => Promise<Role>;\n createRole: (input: RoleInput) => Promise<AuthResult<Role>>;\n updateRole: (id: string, input: RoleUpdateInput, organizationId?: string) => Promise<AuthResult<Role>>;\n deleteRole: (id: string, organizationId?: string) => Promise<AuthResult<null>>;\n\n listPermissions: (params?: { applicationId?: string; roleId?: string | null }) => Promise<Permission[]>;\n createPermission: (input: PermissionInput) => Promise<AuthResult<Permission>>;\n updatePermission: (id: string, input: PermissionUpdateInput) => Promise<AuthResult<Permission>>;\n deletePermission: (id: string) => Promise<AuthResult<null>>;\n\n listUserSessions: (params?: { userId?: string; organizationId?: string | null }) => Promise<UserSession[]>;\n revokeUserSession: (sessionId: string) => Promise<AuthResult<null>>;\n\n listMembers: (organizationId: string) => Promise<OrganizationMember[]>;\n getMember: (organizationId: string, memberId: string) => Promise<OrganizationMember>;\n addMember: (organizationId: string, input: AddMemberInput) => Promise<AuthResult<OrganizationMember>>;\n updateMember: (\n organizationId: string,\n memberId: string,\n input: UpdateMemberInput,\n ) => Promise<AuthResult<OrganizationMember>>;\n /** @deprecated use updateMember */\n updateMemberRole: (\n organizationId: string,\n memberId: string,\n input: UpdateMemberRoleInput,\n ) => Promise<AuthResult<OrganizationMember>>;\n removeMember: (organizationId: string, memberId: string) => Promise<AuthResult<null>>;\n inviteMember: (organizationId: string, input: MemberInviteInput) => Promise<AuthResult<OrganizationInvite>>;\n listInvites: (organizationId: string) => Promise<OrganizationInvite[]>;\n revokeInvite: (organizationId: string, inviteId: string) => Promise<AuthResult<null>>;\n};\n\nexport type UseOrgResult = Pick<\n GeekappsAuthContextValue,\n | \"organizations\"\n | \"currentOrg\"\n | \"currentOrgId\"\n | \"isLoadingOrganizations\"\n | \"refreshOrganizations\"\n | \"setCurrentOrg\"\n | \"createOrganization\"\n | \"lookupTaxId\"\n | \"updateOrganization\"\n | \"deleteOrganization\"\n | \"hasPermission\"\n | \"currentMembership\"\n | \"isLoadingMembership\"\n | \"getMyMembership\"\n | \"refreshMembership\"\n>;\n\nexport type UseAccountsResult = Pick<\n GeekappsAuthContextValue,\n \"accounts\" | \"addAccount\" | \"isLoadingAccounts\" | \"refreshAccounts\" | \"switchAccount\"\n>;\n\nexport type UseUsersResult = Pick<\n GeekappsAuthContextValue,\n \"listUsers\" | \"getUser\" | \"createUser\" | \"updateUser\" | \"deleteUser\"\n>;\n\nexport type UseRolesResult = Pick<\n GeekappsAuthContextValue,\n \"listRoles\" | \"getRole\" | \"createRole\" | \"updateRole\" | \"deleteRole\"\n>;\n\nexport type UsePermissionsResult = Pick<\n GeekappsAuthContextValue,\n \"listPermissions\" | \"createPermission\" | \"updatePermission\" | \"deletePermission\"\n>;\n\nexport type UseSessionsResult = Pick<\n GeekappsAuthContextValue,\n \"listUserSessions\" | \"revokeUserSession\"\n>;\n\nexport type UseMembersResult = Pick<\n GeekappsAuthContextValue,\n | \"listMembers\"\n | \"getMember\"\n | \"addMember\"\n | \"updateMember\"\n | \"updateMemberRole\"\n | \"removeMember\"\n | \"inviteMember\"\n | \"listInvites\"\n | \"revokeInvite\"\n>;\n\nexport type UsePublicOrganizationsResult = Pick<GeekappsAuthContextValue, \"listPublicOrganizations\">;\n\nexport type UseJoinRequestsResult = Pick<\n GeekappsAuthContextValue,\n | \"requestToJoin\"\n | \"getMyJoinRequest\"\n | \"cancelJoinRequest\"\n | \"listJoinRequests\"\n | \"approveJoinRequest\"\n | \"rejectJoinRequest\"\n>;\n\nexport type UseInvitesResult = Pick<\n GeekappsAuthContextValue,\n \"getInvitePreview\" | \"acceptInvite\" | \"rejectInvite\" | \"listMyInvites\" | \"acceptInviteById\" | \"rejectInviteById\"\n>;\n\nconst GeekappsAuthContext = createContext<GeekappsAuthContextValue | null>(null);\n\nexport function GeekappsAuthProvider({\n children,\n basePath = \"/api/auth\",\n initialUser = null,\n initialOrganizations = [],\n initialCurrentOrgId = null,\n}: GeekappsAuthProviderProps): ReactElement {\n const [user, setUser] = useState<User | null>(initialUser);\n const [isLoading, setIsLoading] = useState(true);\n const [accounts, setAccounts] = useState<ConnectedAccount[]>([]);\n const [isLoadingAccounts, setIsLoadingAccounts] = useState(true);\n const [organizations, setOrganizations] = useState<Organization[]>(initialOrganizations);\n const [currentOrgId, setCurrentOrgId] = useState<string | null>(initialCurrentOrgId);\n const [isLoadingOrganizations, setIsLoadingOrganizations] = useState(true);\n\n // As chamadas de role resolvem a organização ativa na hora em que rodam, não\n // na hora em que foram criadas — sem o ref, um callback memoizado ficaria com\n // o org id que existia na primeira render.\n const currentOrgIdRef = useRef(currentOrgId);\n currentOrgIdRef.current = currentOrgId;\n\n const request = useCallback(\n async <T,>(path: string, options: RequestOptions = {}) => {\n const response = await fetch(buildUrl(basePath, path), {\n method: options.method ?? \"GET\",\n credentials: \"include\",\n headers:\n options.body === undefined\n ? undefined\n : {\n \"content-type\": \"application/json\",\n },\n body: options.body === undefined ? undefined : JSON.stringify(options.body),\n });\n\n if (response.status === 401) {\n // O servidor já limpou os cookies: a sessão expirou ou foi revogada no\n // painel. Zera o estado local para a interface parar de mostrar\n // alguém logado, e lança um erro reconhecível em vez de \"401\".\n setUser(null);\n setAccounts([]);\n throw new GeekappsSessionExpiredError();\n }\n\n if (!response.ok) {\n throw await apiErrorFromResponse(response);\n }\n\n if (response.status === 204) {\n return null as T;\n }\n\n return (await response.json()) as T;\n },\n [basePath],\n );\n\n const refreshUser = useCallback(async () => {\n setIsLoading(true);\n try {\n const { user: u } = await request<{ user: User | null }>(\"/me\");\n setUser(u);\n } catch {\n setUser(null);\n } finally {\n setIsLoading(false);\n }\n }, []);\n\n const refreshAccounts = useCallback(async () => {\n setIsLoadingAccounts(true);\n try {\n const { accounts: a } = await request<{ accounts: ConnectedAccount[] }>(\n \"/accounts\",\n );\n setAccounts(a);\n } catch {\n setAccounts([]);\n } finally {\n setIsLoadingAccounts(false);\n }\n }, []);\n\n const refreshOrganizations = useCallback(async () => {\n setIsLoadingOrganizations(true);\n try {\n const { organizations: orgs, currentOrgId: nextCurrentOrgId } =\n await request<{\n organizations: Organization[];\n currentOrgId?: string | null;\n }>(\"/organizations\");\n setOrganizations(orgs);\n setCurrentOrgId((current) => {\n if (nextCurrentOrgId !== undefined) return nextCurrentOrgId ?? null;\n if (current && orgs.some((org) => org.id === current)) return current;\n return orgs[0]?.id ?? null;\n });\n } catch {\n setOrganizations([]);\n setCurrentOrgId(null);\n } finally {\n setIsLoadingOrganizations(false);\n }\n }, []);\n\n useEffect(() => {\n void refreshUser();\n void refreshAccounts();\n void refreshOrganizations();\n }, [refreshAccounts, refreshOrganizations, refreshUser]);\n\n const currentOrg = useMemo(\n () => organizations.find((organization) => organization.id === currentOrgId) ?? null,\n [currentOrgId, organizations],\n );\n\n const [currentMembership, setCurrentMembership] = useState<OrganizationMembership | null>(null);\n const [isLoadingMembership, setIsLoadingMembership] = useState(false);\n\n const getMyMembership = useCallback(\n async (organizationId?: string) => {\n const orgId = organizationId ?? currentOrgId;\n if (!orgId) return null;\n try {\n return await request<OrganizationMembership>(\n `/organizations/${encodeURIComponent(orgId)}/members/me`,\n );\n } catch {\n return null;\n }\n },\n [currentOrgId, request],\n );\n\n const refreshMembership = useCallback(async () => {\n if (!currentOrgId || !user) {\n setCurrentMembership(null);\n return;\n }\n setIsLoadingMembership(true);\n try {\n setCurrentMembership(await getMyMembership(currentOrgId));\n } finally {\n setIsLoadingMembership(false);\n }\n }, [currentOrgId, getMyMembership, user]);\n\n useEffect(() => {\n void refreshMembership();\n }, [refreshMembership]);\n\n const setCurrentOrg = useCallback(\n async (organizationId: string | null) => {\n await request(\"/organizations/active\", {\n method: \"POST\",\n body: { organizationId },\n });\n setCurrentOrgId(organizationId);\n },\n [request],\n );\n\n const signIn = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/sign-in\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n if (options?.authorizationFlowId) url.searchParams.set(\"flow_id\", options.authorizationFlowId);\n const prompt = options?.prompt ?? (options?.silentLogin === false ? \"login\" : undefined);\n if (prompt) url.searchParams.set(\"prompt\", prompt);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const signUp = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/sign-up\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n if (options?.authorizationFlowId) url.searchParams.set(\"flow_id\", options.authorizationFlowId);\n const prompt = options?.prompt ?? (options?.silentLogin === false ? \"login\" : undefined);\n if (prompt) url.searchParams.set(\"prompt\", prompt);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const addAccount = useCallback(\n async (input?: SignInInput) => {\n const options = normalizeSignInOptions(input);\n const url = new URL(buildUrl(basePath, \"/add-account\"), window.location.origin);\n if (options?.redirectTo) url.searchParams.set(\"redirectTo\", options.redirectTo);\n redirectTo(url.toString());\n },\n [basePath],\n );\n\n const signOut = useCallback(async () => {\n await request(\"/sign-out\", { method: \"POST\" });\n setUser(null);\n await refreshAccounts();\n }, [refreshAccounts, request]);\n\n const signOutAll = useCallback(async () => {\n await request(\"/sign-out-all\", { method: \"POST\" });\n setUser(null);\n setAccounts([]);\n }, [request]);\n\n const switchAccount = useCallback(\n async (sessionId: string, options?: SignInOptions) => {\n await request(\"/accounts/switch\", {\n method: \"POST\",\n body: { sessionId },\n });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (options?.redirectTo) redirectTo(options.redirectTo);\n },\n [refreshAccounts, refreshOrganizations, refreshUser, request],\n );\n\n async function toAuthResult<T>(fn: () => Promise<T>): Promise<AuthResult<T>> {\n try {\n return { success: true, data: await fn() };\n } catch (error) {\n if (error instanceof GeekappsApiError) {\n return {\n success: false,\n error: error.message,\n status: error.status,\n code: error.code,\n missingFields: error.missingFields,\n retryAfter: error.retryAfter,\n };\n }\n return { success: false, error: error instanceof Error ? error.message : \"Unexpected error\" };\n }\n }\n\n // ── Invites: precisam do status HTTP cru (401/404/409), não só uma\n // mensagem — request()/toAuthResult() não bastam aqui.\n const getInvitePreview = useCallback(\n (token: string) => request<OrganizationInvitePreview>(`/organizations/invites/${encodeURIComponent(token)}`),\n [request],\n );\n\n const acceptInvite = useCallback(\n async (token: string): Promise<AcceptInviteResult> => {\n const response = await fetch(buildUrl(basePath, \"/organizations/invites/accept\"), {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ token }),\n });\n const data = await response.json().catch(() => null);\n\n if (response.ok && data) {\n return {\n success: true,\n organizationId: data.organizationId,\n organizationName: data.organizationName,\n websiteUrl: data.websiteUrl ?? null,\n };\n }\n if (response.status === 409 && data?.error === \"wrong_account\") {\n return {\n success: false,\n wrongAccount: true,\n currentEmail: String(data.currentEmail ?? \"\"),\n invitedEmail: String(data.invitedEmail ?? \"\"),\n };\n }\n if (response.status === 401 && data?.error === \"login_required\") {\n return { success: false, wrongAccount: false, loginRequired: true };\n }\n return {\n success: false,\n wrongAccount: false,\n loginRequired: false,\n error: typeof data?.error === \"string\" ? data.error : `HTTP ${response.status}`,\n };\n },\n [basePath],\n );\n\n const rejectInvite = useCallback(\n async (token: string): Promise<{ success: true } | { success: false; error: string }> => {\n const response = await fetch(buildUrl(basePath, \"/organizations/invites/reject\"), {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ token }),\n });\n if (response.ok) return { success: true };\n const data = await response.json().catch(() => null);\n return { success: false, error: typeof data?.error === \"string\" ? data.error : `HTTP ${response.status}` };\n },\n [basePath],\n );\n\n const getMyJoinRequest = useCallback(\n async (organizationId: string): Promise<OrganizationJoinRequest | null> => {\n const response = await fetch(buildUrl(basePath, `/organizations/${organizationId}/join-requests/me`), {\n credentials: \"include\",\n });\n if (response.status === 404) return null;\n if (!response.ok) throw new Error(await parseError(response));\n return response.json();\n },\n [basePath],\n );\n\n const value = useMemo<GeekappsAuthContextValue>(\n () => ({\n basePath,\n user,\n isAuthenticated: !isLoading && user !== null,\n isLoading,\n accounts,\n isLoadingAccounts,\n organizations,\n currentOrg,\n currentOrgId,\n currentMembership,\n isLoadingMembership,\n getMyMembership,\n refreshMembership,\n isLoadingOrganizations,\n request,\n signIn,\n signUp,\n addAccount,\n signOut,\n signOutAll,\n refreshUser,\n refreshAccounts,\n switchAccount,\n loginWithPassword: (params) =>\n toAuthResult(async () => {\n const data = await request<LoginResponse>(\"/login/password\", { method: \"POST\", body: params });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (params.redirectTo ?? data.redirectTo) redirectTo(params.redirectTo ?? data.redirectTo!);\n return data;\n }),\n registerWithPassword: (params) =>\n toAuthResult(async () => {\n const data = await request<RegisterResponse>(\"/register/password\", { method: \"POST\", body: params });\n await Promise.all([refreshUser(), refreshAccounts(), refreshOrganizations()]);\n if (params.redirectTo) redirectTo(params.redirectTo);\n return data;\n }),\n startGoogleLogin: (params) => {\n const url = new URL(buildUrl(basePath, \"/login/google\"), window.location.origin);\n if (params?.callbackUrl) url.searchParams.set(\"callbackUrl\", params.callbackUrl);\n if (params?.redirectTo) url.searchParams.set(\"redirectTo\", params.redirectTo);\n if (params?.authorizationFlowId) url.searchParams.set(\"flow_id\", params.authorizationFlowId);\n redirectTo(url.toString());\n },\n joinWaitlist: (params) =>\n toAuthResult(() =>\n request<JoinWaitlistResponse>(\"/waitlist/join\", {\n method: \"POST\",\n body: { client_id: params.clientId, email: params.email, name: params.name },\n }),\n ),\n requestPasswordlessLink: (params) =>\n toAuthResult(() => request(\"/passwordless/link\", { method: \"POST\", body: params })),\n refreshOrganizations,\n setCurrentOrg,\n createOrganization: (input) =>\n toAuthResult(async () => {\n const organization = await request<Organization>(\"/organizations\", { method: \"POST\", body: input });\n await refreshOrganizations();\n setCurrentOrgId(organization.id);\n return organization;\n }),\n lookupTaxId: (value, type = \"br_cnpj\") =>\n toAuthResult(() =>\n request<TaxIdLookupResult>(\n `/organizations/tax-id/lookup?type=${encodeURIComponent(type)}&value=${encodeURIComponent(value)}`,\n ),\n ),\n updateOrganization: (id, input) =>\n toAuthResult(async () => {\n const organization = await request<Organization>(`/organizations/${id}`, { method: \"PATCH\", body: input });\n await refreshOrganizations();\n return organization;\n }),\n deleteOrganization: (id) =>\n toAuthResult(async () => {\n await request<null>(`/organizations/${id}`, { method: \"DELETE\" });\n await refreshOrganizations();\n return null;\n }),\n hasPermission: async (options) => {\n try {\n const data = await request<{ allowed: boolean }>(\"/permissions/check\", {\n method: \"POST\",\n body: options,\n });\n return data.allowed;\n } catch {\n return false;\n }\n },\n listUsers: (params) => {\n const query = new URLSearchParams();\n if (params?.organizationId) query.set(\"organizationId\", params.organizationId);\n return request<User[]>(`/users${query.size ? `?${query.toString()}` : \"\"}`);\n },\n getUser: (id) => request<User>(`/users/${id}`),\n createUser: (input) => toAuthResult(() => request<User>(\"/users\", { method: \"POST\", body: input })),\n updateUser: (id, input) => toAuthResult(() => request<User>(`/users/${id}`, { method: \"PATCH\", body: input })),\n deleteUser: (id) =>\n toAuthResult(async () => {\n await request<null>(`/users/${id}`, { method: \"DELETE\" });\n return null;\n }),\n // Roles são sempre resolvidas no escopo de uma organização — o\n // auth-server não expõe /roles solto. Sem organizationId explícito,\n // usa a organização ativa; sem nenhuma das duas não há o que consultar.\n listRoles: async (params) => {\n const organizationId = params?.organizationId ?? currentOrgIdRef.current;\n if (!organizationId) {\n throw new Error(\n \"listRoles: informe organizationId — não há organização ativa para resolver as roles.\",\n );\n }\n const roles = await request<Role[]>(`/organizations/${organizationId}/roles`);\n // O endpoint devolve a lista inteira; a separação system/custom é\n // feita aqui para manter o contrato que os consumidores já usam.\n return {\n systemRoles: roles.filter((role) => role.isDefault),\n customRoles: roles.filter((role) => !role.isDefault),\n };\n },\n getRole: (id, _type, organizationId) => {\n const orgId = organizationId ?? currentOrgIdRef.current;\n if (!orgId) {\n throw new Error(\"getRole: informe organizationId — não há organização ativa.\");\n }\n return request<Role>(`/organizations/${orgId}/roles/${id}`);\n },\n createRole: ({ organizationId, permissionDefinitionIds, applicationId: _applicationId, ...rest }) =>\n toAuthResult(() => {\n const orgId = organizationId ?? currentOrgIdRef.current;\n if (!orgId) {\n throw new Error(\"createRole: informe organizationId — não há organização ativa.\");\n }\n return request<Role>(`/organizations/${orgId}/roles`, {\n method: \"POST\",\n // O auth-server espera permissionIds; permissionDefinitionIds é o\n // nome herdado no SDK.\n body: { ...rest, permissionIds: permissionDefinitionIds ?? [] },\n });\n }),\n updateRole: (id, { permissionDefinitionIds, ...rest }, organizationId) =>\n toAuthResult(() => {\n const orgId = organizationId ?? currentOrgIdRef.current;\n if (!orgId) {\n throw new Error(\"updateRole: informe organizationId — não há organização ativa.\");\n }\n return request<Role>(`/organizations/${orgId}/roles/${id}`, {\n method: \"PATCH\",\n body: {\n ...rest,\n ...(permissionDefinitionIds ? { permissionIds: permissionDefinitionIds } : {}),\n },\n });\n }),\n deleteRole: (id, organizationId) =>\n toAuthResult(async () => {\n const orgId = organizationId ?? currentOrgIdRef.current;\n if (!orgId) {\n throw new Error(\"deleteRole: informe organizationId — não há organização ativa.\");\n }\n await request<null>(`/organizations/${orgId}/roles/${id}`, { method: \"DELETE\" });\n return null;\n }),\n listPermissions: (params) => {\n const query = new URLSearchParams();\n if (params?.applicationId) query.set(\"applicationId\", params.applicationId);\n if (params?.roleId) query.set(\"roleId\", params.roleId);\n return request<Permission[]>(`/permissions${query.size ? `?${query.toString()}` : \"\"}`);\n },\n createPermission: (input) =>\n toAuthResult(() => request<Permission>(\"/permissions\", { method: \"POST\", body: input })),\n updatePermission: (id, input) =>\n toAuthResult(() => request<Permission>(`/permissions/${id}`, { method: \"PATCH\", body: input })),\n deletePermission: (id) =>\n toAuthResult(async () => {\n await request<null>(`/permissions/${id}`, { method: \"DELETE\" });\n return null;\n }),\n listUserSessions: (params) => {\n const query = new URLSearchParams();\n if (params?.userId) query.set(\"userId\", params.userId);\n if (params?.organizationId) query.set(\"organizationId\", params.organizationId);\n return request<UserSession[]>(`/sessions${query.size ? `?${query.toString()}` : \"\"}`);\n },\n revokeUserSession: (sessionId) =>\n toAuthResult(async () => {\n await request<null>(`/sessions/${sessionId}`, { method: \"DELETE\" });\n return null;\n }),\n listMembers: (organizationId) =>\n request<OrganizationMember[]>(`/organizations/${organizationId}/members`),\n getMember: (organizationId, memberId) =>\n request<OrganizationMember>(`/organizations/${organizationId}/members/${memberId}`),\n addMember: (organizationId, input) =>\n toAuthResult(() =>\n request<OrganizationMember>(`/organizations/${organizationId}/members`, {\n method: \"POST\",\n body: input,\n }),\n ),\n updateMember: (organizationId, memberId, input) =>\n toAuthResult(() =>\n request<OrganizationMember>(`/organizations/${organizationId}/members/${memberId}`, {\n method: \"PATCH\",\n body: input,\n }),\n ),\n updateMemberRole: (organizationId, memberId, input) =>\n toAuthResult(() =>\n request<OrganizationMember>(`/organizations/${organizationId}/members/${memberId}`, {\n method: \"PATCH\",\n body: input,\n }),\n ),\n removeMember: (organizationId, memberId) =>\n toAuthResult(async () => {\n await request<null>(`/organizations/${organizationId}/members/${memberId}`, { method: \"DELETE\" });\n return null;\n }),\n inviteMember: (organizationId, input) =>\n toAuthResult(() =>\n request<OrganizationInvite>(`/organizations/${organizationId}/invites`, {\n method: \"POST\",\n body: input,\n }),\n ),\n listInvites: (organizationId) =>\n request<OrganizationInvite[]>(`/organizations/${organizationId}/invites`),\n revokeInvite: (organizationId, inviteId) =>\n toAuthResult(async () => {\n await request<null>(`/organizations/${organizationId}/invites/${inviteId}`, { method: \"DELETE\" });\n return null;\n }),\n listPublicOrganizations: () => request<PublicOrganization[]>(\"/organizations/public\"),\n requestToJoin: (organizationId, input) =>\n toAuthResult(() =>\n request<OrganizationJoinRequest>(`/organizations/${organizationId}/join-requests`, {\n method: \"POST\",\n body: input ?? {},\n }),\n ),\n getMyJoinRequest,\n cancelJoinRequest: (organizationId) =>\n toAuthResult(async () => {\n await request<null>(`/organizations/${organizationId}/join-requests/me`, { method: \"DELETE\" });\n return null;\n }),\n listJoinRequests: (organizationId) =>\n request<OrganizationJoinRequest[]>(`/organizations/${organizationId}/join-requests`),\n approveJoinRequest: (organizationId, requestId) =>\n toAuthResult(() =>\n request<OrganizationJoinRequest>(`/organizations/${organizationId}/join-requests/${requestId}/approve`, {\n method: \"POST\",\n }),\n ),\n rejectJoinRequest: (organizationId, requestId) =>\n toAuthResult(() =>\n request<OrganizationJoinRequest>(`/organizations/${organizationId}/join-requests/${requestId}/reject`, {\n method: \"POST\",\n }),\n ),\n getInvitePreview,\n acceptInvite,\n rejectInvite,\n listMyInvites: () => request<MyOrganizationInvite[]>(\"/me/invites\"),\n acceptInviteById: async (inviteId) => {\n const result = await request<{ success: true; organizationId: string; organizationName: string }>(\n `/me/invites/${encodeURIComponent(inviteId)}/accept`,\n { method: \"POST\" },\n );\n await refreshOrganizations();\n return result;\n },\n rejectInviteById: async (inviteId) => {\n await request(`/me/invites/${encodeURIComponent(inviteId)}/reject`, { method: \"POST\" });\n },\n }),\n [\n accounts,\n acceptInvite,\n addAccount,\n basePath,\n currentOrg,\n currentOrgId,\n currentMembership,\n isLoadingMembership,\n getMyMembership,\n refreshMembership,\n getInvitePreview,\n getMyJoinRequest,\n isLoading,\n isLoadingAccounts,\n isLoadingOrganizations,\n organizations,\n refreshAccounts,\n refreshOrganizations,\n refreshUser,\n rejectInvite,\n request,\n setCurrentOrg,\n signIn,\n signOut,\n signOutAll,\n signUp,\n switchAccount,\n user,\n ],\n );\n\n return <GeekappsAuthContext.Provider value={value}>{children}</GeekappsAuthContext.Provider>;\n}\n\nexport function useAuth(): GeekappsAuthContextValue {\n const context = useContext(GeekappsAuthContext);\n if (!context) throw new Error(\"useAuth must be used inside GeekappsAuthProvider\");\n return context;\n}\n\nexport function useOrg(): UseOrgResult {\n const context = useAuth();\n return {\n organizations: context.organizations,\n currentOrg: context.currentOrg,\n currentOrgId: context.currentOrgId,\n isLoadingOrganizations: context.isLoadingOrganizations,\n refreshOrganizations: context.refreshOrganizations,\n setCurrentOrg: context.setCurrentOrg,\n createOrganization: context.createOrganization,\n lookupTaxId: context.lookupTaxId,\n updateOrganization: context.updateOrganization,\n deleteOrganization: context.deleteOrganization,\n hasPermission: context.hasPermission,\n currentMembership: context.currentMembership,\n isLoadingMembership: context.isLoadingMembership,\n getMyMembership: context.getMyMembership,\n refreshMembership: context.refreshMembership,\n };\n}\n\nexport function useAccounts(): UseAccountsResult {\n const context = useAuth();\n return {\n accounts: context.accounts,\n addAccount: context.addAccount,\n isLoadingAccounts: context.isLoadingAccounts,\n refreshAccounts: context.refreshAccounts,\n switchAccount: context.switchAccount,\n };\n}\n\nexport function useUsers(): UseUsersResult {\n const context = useAuth();\n return {\n listUsers: context.listUsers,\n getUser: context.getUser,\n createUser: context.createUser,\n updateUser: context.updateUser,\n deleteUser: context.deleteUser,\n };\n}\n\nexport function useRoles(): UseRolesResult {\n const context = useAuth();\n return {\n listRoles: context.listRoles,\n getRole: context.getRole,\n createRole: context.createRole,\n updateRole: context.updateRole,\n deleteRole: context.deleteRole,\n };\n}\n\nexport function usePermissions(): UsePermissionsResult {\n const context = useAuth();\n return {\n listPermissions: context.listPermissions,\n createPermission: context.createPermission,\n updatePermission: context.updatePermission,\n deletePermission: context.deletePermission,\n };\n}\n\nexport function useSessions(): UseSessionsResult {\n const context = useAuth();\n return {\n listUserSessions: context.listUserSessions,\n revokeUserSession: context.revokeUserSession,\n };\n}\n\nexport function useMembers(): UseMembersResult {\n const context = useAuth();\n return {\n listMembers: context.listMembers,\n getMember: context.getMember,\n addMember: context.addMember,\n updateMember: context.updateMember,\n updateMemberRole: context.updateMemberRole,\n removeMember: context.removeMember,\n inviteMember: context.inviteMember,\n listInvites: context.listInvites,\n revokeInvite: context.revokeInvite,\n };\n}\n\n/**\n * Descoberta de organizações PÚBLICAS do app — bem separado de `useOrg()`,\n * que lida com as organizações do próprio usuário (as que ele já é\n * membro/dono). `usePublicOrganizations()` nunca retorna organizações\n * privadas, e não exige que o usuário já pertença a elas.\n */\nexport function usePublicOrganizations(): UsePublicOrganizationsResult {\n const context = useAuth();\n return {\n listPublicOrganizations: context.listPublicOrganizations,\n };\n}\n\n/**\n * Solicitações de entrada em organizações públicas: um usuário pede pra\n * entrar (requestToJoin) e um admin da organização aprova/rejeita\n * (approveJoinRequest/rejectJoinRequest, exigem permissão org:members:add).\n */\nexport function useJoinRequests(): UseJoinRequestsResult {\n const context = useAuth();\n return {\n requestToJoin: context.requestToJoin,\n getMyJoinRequest: context.getMyJoinRequest,\n cancelJoinRequest: context.cancelJoinRequest,\n listJoinRequests: context.listJoinRequests,\n approveJoinRequest: context.approveJoinRequest,\n rejectJoinRequest: context.rejectJoinRequest,\n };\n}\n\n/**\n * Aceite/recusa de convite por email — chamadas a partir do ?invite_token=\n * que este app recebe na sua própria redirectUri (a que foi passada em\n * useMembers().inviteMember). getInvitePreview funciona sem sessão\n * (currentAccount vem null); rejectInvite não exige login; acceptInvite\n * retorna loginRequired:true se não houver sessão.\n */\nexport function useInvites(): UseInvitesResult {\n const context = useAuth();\n return {\n getInvitePreview: context.getInvitePreview,\n acceptInvite: context.acceptInvite,\n rejectInvite: context.rejectInvite,\n listMyInvites: context.listMyInvites,\n acceptInviteById: context.acceptInviteById,\n rejectInviteById: context.rejectInviteById,\n };\n}\n\n// ── Service Accounts ─────────────────────────────────────────────────────────\n\nexport type ServiceAccount = {\n id: string;\n membershipId: string;\n organizationId: string;\n applicationId: string | null;\n name: string;\n status: \"active\" | \"inactive\" | \"suspended\";\n serviceId: string | null;\n roleAssignment: { role: { id: string; key: string; name: string } } | null;\n createdAt: string;\n updatedAt: string;\n};\n\nexport type ServiceAccountWithSecret = ServiceAccount & { serviceSecret: string };\n\nexport type CreateServiceAccountInput = {\n organizationId: string;\n applicationId?: string;\n name: string;\n description?: string;\n roleId?: string;\n};\n\nexport type UseServiceAccountResult = {\n listServiceAccounts: (params: { organizationId: string; applicationId?: string }) => Promise<ServiceAccount[]>;\n createServiceAccount: (input: CreateServiceAccountInput) => Promise<ServiceAccountWithSecret>;\n updateServiceAccountRole: (id: string, roleId: string | null) => Promise<void>;\n revokeServiceAccount: (id: string) => Promise<void>;\n rotateServiceAccountSecret: (id: string) => Promise<{ serviceId: string; serviceSecret: string }>;\n deleteServiceAccount: (id: string) => Promise<void>;\n};\n\nexport function useServiceAccount(): UseServiceAccountResult {\n const { request } = useAuth();\n\n const listServiceAccounts = useCallback(\n (params: { organizationId: string; applicationId?: string }) => {\n const query = new URLSearchParams({ organizationId: params.organizationId });\n if (params.applicationId) query.set(\"applicationId\", params.applicationId);\n return request<ServiceAccount[]>(`/service-accounts?${query.toString()}`);\n },\n [request],\n );\n\n const createServiceAccount = useCallback(\n (input: CreateServiceAccountInput) =>\n request<ServiceAccountWithSecret>(\"/service-accounts\", { method: \"POST\", body: input }),\n [request],\n );\n\n const updateServiceAccountRole = useCallback(\n async (id: string, roleId: string | null) => {\n await request<void>(`/service-accounts/${id}`, { method: \"PATCH\", body: { roleId } });\n },\n [request],\n );\n\n const revokeServiceAccount = useCallback(\n async (id: string) => {\n await request<void>(`/service-accounts/${id}/revoke`, { method: \"POST\" });\n },\n [request],\n );\n\n const rotateServiceAccountSecret = useCallback(\n (id: string) =>\n request<{ serviceId: string; serviceSecret: string }>(`/service-accounts/${id}/rotate-secret`, {\n method: \"POST\",\n }),\n [request],\n );\n\n const deleteServiceAccount = useCallback(\n async (id: string) => {\n await request<null>(`/service-accounts/${id}`, { method: \"DELETE\" });\n },\n [request],\n );\n\n return {\n listServiceAccounts,\n createServiceAccount,\n updateServiceAccountRole,\n revokeServiceAccount,\n rotateServiceAccountSecret,\n deleteServiceAccount,\n };\n}\n"],"mappings":"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","names":["value"]}
|
package/dist/connections.d.ts
CHANGED
|
@@ -40,11 +40,12 @@ interface GeekappsConnections {
|
|
|
40
40
|
* • `missing_scope` — a conexão não tem o escopo da rota (peça de novo com `connectApp`);
|
|
41
41
|
* • `connection_revoked` — revogada, token inválido ou o usuário saiu da organização;
|
|
42
42
|
* • `connection_expired` — passou da validade escolhida no consent;
|
|
43
|
+
* • `app_not_allowed` — a app consumidora e a alvo são de organizações diferentes (não se conectam);
|
|
43
44
|
* • `validation_error` — a app alvo recusou a entrada (400/422);
|
|
44
45
|
* • `network_error` — não deu para falar com o auth-server ou a app alvo;
|
|
45
46
|
* • `unknown` — o resto (veja `status`, `reason` e `body`).
|
|
46
47
|
*/
|
|
47
|
-
type AppConnectionErrorCode = "missing_scope" | "connection_revoked" | "connection_expired" | "validation_error" | "network_error" | "unknown";
|
|
48
|
+
type AppConnectionErrorCode = "missing_scope" | "connection_revoked" | "connection_expired" | "app_not_allowed" | "validation_error" | "network_error" | "unknown";
|
|
48
49
|
/** Erro de App Connection — `code` dá pra tratar; `reason` é o código cru do servidor. */
|
|
49
50
|
declare class AppConnectionError extends Error {
|
|
50
51
|
readonly status: number;
|
package/dist/connections.js
CHANGED
|
@@ -20,13 +20,19 @@ __export(typegen_exports, {
|
|
|
20
20
|
});
|
|
21
21
|
import { mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync, existsSync } from "fs";
|
|
22
22
|
import { join, resolve } from "path";
|
|
23
|
-
async function fetchCatalog(
|
|
24
|
-
const
|
|
25
|
-
|
|
23
|
+
async function fetchCatalog(credentials) {
|
|
24
|
+
const issuer = credentials.issuer.replace(/\/$/, "");
|
|
25
|
+
const asUser = "accessToken" in credentials;
|
|
26
|
+
const response = await fetch(`${issuer}${asUser ? "/me/connections/catalog" : "/connections/catalog"}`, {
|
|
27
|
+
headers: {
|
|
28
|
+
authorization: asUser ? `Bearer ${credentials.accessToken}` : `Basic ${Buffer.from(`${credentials.clientId}:${credentials.clientSecret}`).toString("base64")}`
|
|
29
|
+
},
|
|
26
30
|
cache: "no-store"
|
|
27
31
|
});
|
|
28
32
|
if (!response.ok) {
|
|
29
|
-
throw new Error(
|
|
33
|
+
throw new Error(
|
|
34
|
+
asUser ? `cat\xE1logo indispon\xEDvel (${response.status}) \u2014 rode \`geekapps login\` de novo` : `cat\xE1logo indispon\xEDvel (${response.status}) \u2014 confira GEEKAPPS_AUTH_CLIENT_ID e GEEKAPPS_AUTH_CLIENT_SECRET`
|
|
35
|
+
);
|
|
30
36
|
}
|
|
31
37
|
return await response.json();
|
|
32
38
|
}
|
|
@@ -235,6 +241,8 @@ function toErrorCode(status, reason) {
|
|
|
235
241
|
return "missing_scope";
|
|
236
242
|
case "connection_expired":
|
|
237
243
|
return "connection_expired";
|
|
244
|
+
case "app_not_allowed":
|
|
245
|
+
return "app_not_allowed";
|
|
238
246
|
case "connection_inactive":
|
|
239
247
|
case "connection_revoked":
|
|
240
248
|
case "invalid_token":
|
|
@@ -601,23 +609,6 @@ function createConnections(config = {}) {
|
|
|
601
609
|
});
|
|
602
610
|
}
|
|
603
611
|
var connections = createConnections();
|
|
604
|
-
var TYPES_AUGMENT_MODULE = "@geekapps/auth-nextjs/connections";
|
|
605
|
-
async function syncTypes() {
|
|
606
|
-
const { issuer, clientId, clientSecret } = resolveConfig({});
|
|
607
|
-
if (!clientId || !clientSecret) return;
|
|
608
|
-
try {
|
|
609
|
-
const { generateConnectionTypes: generateConnectionTypes2 } = await Promise.resolve().then(() => (init_typegen(), typegen_exports));
|
|
610
|
-
await generateConnectionTypes2({
|
|
611
|
-
credentials: { issuer, clientId, clientSecret },
|
|
612
|
-
augment: TYPES_AUGMENT_MODULE
|
|
613
|
-
});
|
|
614
|
-
} catch {
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
if (process.env.NODE_ENV === "development" && process.env.GEEKAPPS_CONNECTIONS_TYPES !== "off") {
|
|
618
|
-
void syncTypes();
|
|
619
|
-
setInterval(() => void syncTypes(), 6e4).unref?.();
|
|
620
|
-
}
|
|
621
612
|
export {
|
|
622
613
|
AppConnectionError,
|
|
623
614
|
completeAppConnection,
|