@adonis-agora/authkit-react 0.26.0 → 1.0.0-rc.1

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.
Files changed (36) hide show
  1. package/CHANGELOG.md +699 -0
  2. package/README.md +29 -19
  3. package/build/index.d.ts +3 -18
  4. package/build/index.js +2 -9
  5. package/build/src/client/client.d.ts +12 -21
  6. package/build/src/client/client.js +7 -15
  7. package/build/src/client/types.d.ts +54 -17
  8. package/build/src/components/authorized_apps.js +17 -13
  9. package/build/src/components/organization_profile.js +31 -39
  10. package/build/src/components/organization_switcher.js +25 -9
  11. package/build/src/components/user_profile.js +13 -7
  12. package/build/src/config.d.ts +0 -6
  13. package/build/src/config.js +0 -12
  14. package/build/src/hooks/use_resource.d.ts +0 -8
  15. package/build/src/hooks/use_resource.js +0 -22
  16. package/build/src/queries/account/index.d.ts +11 -1
  17. package/build/src/queries/account/index.js +14 -0
  18. package/build/src/queries/admin/index.d.ts +6 -21
  19. package/build/src/queries/keys.d.ts +1 -0
  20. package/build/src/queries/keys.js +1 -0
  21. package/package.json +12 -11
  22. package/skills/authkit-react-auth/SKILL.md +39 -22
  23. package/build/src/hooks/use_authorized_apps.d.ts +0 -16
  24. package/build/src/hooks/use_authorized_apps.js +0 -15
  25. package/build/src/hooks/use_org_invitations.d.ts +0 -19
  26. package/build/src/hooks/use_org_invitations.js +0 -20
  27. package/build/src/hooks/use_organization.d.ts +0 -23
  28. package/build/src/hooks/use_organization.js +0 -10
  29. package/build/src/hooks/use_organizations.d.ts +0 -18
  30. package/build/src/hooks/use_organizations.js +0 -14
  31. package/build/src/hooks/use_profile.d.ts +0 -13
  32. package/build/src/hooks/use_profile.js +0 -32
  33. package/build/src/hooks/use_sessions.d.ts +0 -16
  34. package/build/src/hooks/use_sessions.js +0 -15
  35. package/build/src/hooks/use_switch_organization.d.ts +0 -7
  36. package/build/src/hooks/use_switch_organization.js +0 -42
@@ -1,17 +1,33 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
2
3
  import { createElement, useState } from 'react';
3
4
  import { useAuthkitConfig } from '../config.js';
4
- import { useOrganizations } from '../hooks/use_organizations.js';
5
- import { useSwitchOrganization } from '../hooks/use_switch_organization.js';
5
+ import { useAccountActivateOrgMutationOptions, useAccountDeactivateOrgMutationOptions, useAccountOrgsQueryOptions, } from '../queries/account/index.js';
6
+ import { authkitKeys } from '../queries/keys.js';
6
7
  import { useAuth } from '../use_auth.js';
7
8
  function OrganizationSwitcherInner({ personalAccountLabel = 'Conta pessoal', className, }) {
8
9
  const { isAuthenticated } = useAuth();
9
- const { data: orgs, activeOrgId, supported } = useOrganizations();
10
- const { activate, deactivate, loading: switching } = useSwitchOrganization();
10
+ const qc = useQueryClient();
11
+ const query = useQuery({ ...useAccountOrgsQueryOptions(), enabled: isAuthenticated });
12
+ const onSwitched = () => Promise.all([
13
+ qc.invalidateQueries({ queryKey: authkitKeys.account.orgs() }),
14
+ qc.invalidateQueries({ queryKey: authkitKeys.account.me() }),
15
+ ]);
16
+ const activate = useMutation({
17
+ ...useAccountActivateOrgMutationOptions(),
18
+ onSuccess: onSwitched,
19
+ });
20
+ const deactivate = useMutation({
21
+ ...useAccountDeactivateOrgMutationOptions(),
22
+ onSuccess: onSwitched,
23
+ });
11
24
  const [open, setOpen] = useState(false);
12
- if (!isAuthenticated || !supported)
25
+ if (!isAuthenticated || !query.data?.supported)
13
26
  return null;
14
- const activeOrg = orgs?.find((o) => o.id === activeOrgId) ?? null;
27
+ const orgs = query.data.orgs;
28
+ const activeOrgId = query.data.activeOrgId;
29
+ const switching = activate.isPending || deactivate.isPending;
30
+ const activeOrg = orgs.find((o) => o.id === activeOrgId) ?? null;
15
31
  const label = activeOrg ? activeOrg.name : personalAccountLabel;
16
32
  const trigger = createElement('button', {
17
33
  type: 'button',
@@ -35,9 +51,9 @@ function OrganizationSwitcherInner({ personalAccountLabel = 'Conta pessoal', cla
35
51
  onClick: async () => {
36
52
  setOpen(false);
37
53
  if (activeOrgId)
38
- await deactivate();
54
+ await deactivate.mutateAsync();
39
55
  },
40
- }, createElement('span', { className: 'authkit-orgswitcher__item-name' }, personalAccountLabel)), ...(orgs ?? []).map((org) => createElement('button', {
56
+ }, createElement('span', { className: 'authkit-orgswitcher__item-name' }, personalAccountLabel)), ...orgs.map((org) => createElement('button', {
41
57
  key: org.id,
42
58
  type: 'button',
43
59
  className: [
@@ -51,7 +67,7 @@ function OrganizationSwitcherInner({ personalAccountLabel = 'Conta pessoal', cla
51
67
  onClick: async () => {
52
68
  setOpen(false);
53
69
  if (!org.isActive)
54
- await activate(org.id);
70
+ await activate.mutateAsync(org.id);
55
71
  },
56
72
  }, createElement('span', { className: 'authkit-orgswitcher__item-name' }, org.name), createElement('span', { className: 'authkit-orgswitcher__item-role' }, org.role))))
57
73
  : null;
@@ -1,31 +1,37 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
2
3
  import { createElement, useState } from 'react';
3
4
  import { useAuthkitConfig } from '../config.js';
4
- import { useProfile } from '../hooks/use_profile.js';
5
+ import { useUpdateProfileMutationOptions } from '../queries/account/index.js';
6
+ import { authkitKeys } from '../queries/keys.js';
5
7
  import { useAuth } from '../use_auth.js';
6
8
  import { Avatar } from './avatar.js';
7
9
  function UserProfileInner({ className }) {
8
10
  const { user, isAuthenticated } = useAuth();
9
- const { actions, loading, error } = useProfile();
11
+ const qc = useQueryClient();
12
+ const update = useMutation({
13
+ ...useUpdateProfileMutationOptions(),
14
+ onSuccess: () => qc.invalidateQueries({ queryKey: authkitKeys.account.me() }),
15
+ });
10
16
  const [name, setName] = useState(user?.name ?? '');
11
17
  if (!isAuthenticated || !user)
12
18
  return null;
13
19
  const onSubmit = (e) => {
14
20
  e.preventDefault();
15
- void actions.update({ name });
21
+ update.mutate({ name });
16
22
  };
17
23
  return createElement('div', { className: ['authkit-card', 'authkit-profile', className].filter(Boolean).join(' ') }, createElement('div', { className: 'authkit-profile__header' }, createElement(Avatar, { user, size: 56 }), createElement('div', null, createElement('div', { className: 'authkit-profile__name' }, user.name ?? user.email), createElement('div', { className: 'authkit-profile__email' }, user.email))), createElement('form', { className: 'authkit-profile__form', onSubmit }, createElement('label', { className: 'authkit-label', htmlFor: 'authkit-profile-name' }, 'Nome'), createElement('input', {
18
24
  id: 'authkit-profile-name',
19
25
  className: 'authkit-input',
20
26
  value: name,
21
27
  onChange: (e) => setName(e.target.value),
22
- }), error
23
- ? createElement('p', { className: 'authkit-error', role: 'alert' }, error.message)
28
+ }), update.error
29
+ ? createElement('p', { className: 'authkit-error', role: 'alert' }, update.error.message)
24
30
  : null, createElement('button', {
25
31
  type: 'submit',
26
32
  className: 'authkit-button authkit-button--primary',
27
- disabled: loading,
28
- }, loading ? 'Salvando…' : 'Salvar')));
33
+ disabled: update.isPending,
34
+ }, update.isPending ? 'Salvando…' : 'Salvar')));
29
35
  }
30
36
  export function UserProfile(props) {
31
37
  const { idp } = useAuthkitConfig();
@@ -1,10 +1,4 @@
1
1
  export interface AuthkitEndpoints {
2
- profile: string;
3
- sessions: string;
4
- apps: string;
5
- passkeys: string;
6
- orgs: string;
7
- orgInvitations: string;
8
2
  can: string;
9
3
  }
10
4
  export type AuthkitIdpMode = 'authkit' | 'external';
@@ -5,12 +5,6 @@ export const DEFAULT_CONFIG = {
5
5
  logoutUrl: '/account/logout',
6
6
  profileUrl: '/account/security',
7
7
  endpoints: {
8
- profile: '/account/security/profile',
9
- sessions: '/account/security',
10
- apps: '/account/apps',
11
- passkeys: '/account/mfa/passkeys',
12
- orgs: '/account/orgs/json',
13
- orgInvitations: '/account/orgs/invitations/json',
14
8
  can: '/authz/can',
15
9
  },
16
10
  };
@@ -20,12 +14,6 @@ export function resolveConfig(config) {
20
14
  logoutUrl: config?.logoutUrl ?? DEFAULT_CONFIG.logoutUrl,
21
15
  profileUrl: config?.profileUrl ?? DEFAULT_CONFIG.profileUrl,
22
16
  endpoints: {
23
- profile: config?.endpoints?.profile ?? DEFAULT_CONFIG.endpoints.profile,
24
- sessions: config?.endpoints?.sessions ?? DEFAULT_CONFIG.endpoints.sessions,
25
- apps: config?.endpoints?.apps ?? DEFAULT_CONFIG.endpoints.apps,
26
- passkeys: config?.endpoints?.passkeys ?? DEFAULT_CONFIG.endpoints.passkeys,
27
- orgs: config?.endpoints?.orgs ?? DEFAULT_CONFIG.endpoints.orgs,
28
- orgInvitations: config?.endpoints?.orgInvitations ?? DEFAULT_CONFIG.endpoints.orgInvitations,
29
17
  can: config?.endpoints?.can ?? config?.canPath ?? DEFAULT_CONFIG.endpoints.can,
30
18
  },
31
19
  csrfToken: config?.csrfToken,
@@ -1,11 +1,3 @@
1
- export interface ResourceState<T> {
2
- data: T | null;
3
- loading: boolean;
4
- error: Error | null;
5
- }
6
1
  export declare function jsonRequest<T>(url: string, init?: RequestInit & {
7
2
  csrfToken?: string;
8
3
  }): Promise<T>;
9
- export declare function useResource<T>(url: string, csrfToken?: string): ResourceState<T> & {
10
- refetch: () => Promise<void>;
11
- };
@@ -1,4 +1,3 @@
1
- import { useCallback, useEffect, useState } from 'react';
2
1
  export async function jsonRequest(url, init = {}) {
3
2
  const { csrfToken, headers, ...rest } = init;
4
3
  const res = await fetch(url, {
@@ -25,24 +24,3 @@ export async function jsonRequest(url, init = {}) {
25
24
  const text = await res.text();
26
25
  return (text ? JSON.parse(text) : null);
27
26
  }
28
- export function useResource(url, csrfToken) {
29
- const [state, setState] = useState({
30
- data: null,
31
- loading: true,
32
- error: null,
33
- });
34
- const refetch = useCallback(async () => {
35
- setState((s) => ({ ...s, loading: true, error: null }));
36
- try {
37
- const data = await jsonRequest(url, { csrfToken });
38
- setState({ data, loading: false, error: null });
39
- }
40
- catch (err) {
41
- setState({ data: null, loading: false, error: err });
42
- }
43
- }, [url, csrfToken]);
44
- useEffect(() => {
45
- void refetch();
46
- }, [refetch]);
47
- return { ...state, refetch };
48
- }
@@ -1,4 +1,4 @@
1
- import type { AcceptOrgInvitationResult, AccountAppsResult, AccountLoginMethodsResult, AccountMe, AccountMfaStatus, AccountOrgDetail, AccountOrgInvitationsResult, AccountOrgsResult, AccountPasskeysResult, AccountSecurityOverview, AccountSessionsResult, AccountTokensResult, ActivateOrgResult, ChangePasswordInput, CreateAccountOrgInput, CreatedAccountOrgResult, CreatedOrgInvitationResult, CreatedPatResult, CreateTokenInput, DeactivateOrgResult, EmailChangeResult, LeaveOrgResult, MfaConfirmResult, MfaDisableResult, MfaEnrollResult, MfaRecoveryCodesResult, OkResult, RemoveOrgMemberResult, RemovePasskeyResult, RequestEmailChangeInput, RevokeAllResult, RevokeAppResult, RevokeOrgInvitationResult, RevokeOthersResult, RevokeSessionResult, RevokeTokenResult, UpdateLoginMethodsResult, UpdateOrgMemberRoleResult, UpdateProfileInput, UpdateProfileResult, UserLoginMethodsInput } from '../../client/types.js';
1
+ import type { AcceptOrgInvitationResult, AccountAgentsResult, AccountAppsResult, AccountLoginMethodsResult, AccountMe, AccountMfaStatus, AccountOrgDetail, AccountOrgInvitationsResult, AccountOrgsResult, AccountPasskeysResult, AccountSecurityOverview, AccountSessionsResult, AccountTokensResult, ActivateOrgResult, ChangePasswordInput, CreateAccountOrgInput, CreatedAccountOrgResult, CreatedOrgInvitationResult, CreatedPatResult, CreateTokenInput, DeactivateOrgResult, EmailChangeResult, LeaveOrgResult, MfaConfirmResult, MfaDisableResult, MfaEnrollResult, MfaRecoveryCodesResult, OkResult, RemoveOrgMemberResult, RemovePasskeyResult, RequestEmailChangeInput, RevokeAllResult, RevokeAppResult, RevokeOrgInvitationResult, RevokeOthersResult, RevokeSessionResult, RevokeTokenResult, UpdateLoginMethodsResult, UpdateOrgMemberRoleResult, UpdateProfileInput, UpdateProfileResult, UserLoginMethodsInput } from '../../client/types.js';
2
2
  import { type RegisterPasskeyJsonDeps } from '../../passkey/json_registration.js';
3
3
  export declare function useMeQueryOptions(): {
4
4
  queryKey: readonly ["authkit", "account", "me"];
@@ -48,6 +48,16 @@ export declare function useRevokeAppMutationOptions(): {
48
48
  mutationKey: string[];
49
49
  mutationFn: (clientId: string) => Promise<RevokeAppResult>;
50
50
  };
51
+ export declare function useAccountAgentsQueryOptions(): {
52
+ queryKey: readonly ["authkit", "account", "agents"];
53
+ queryFn: () => Promise<AccountAgentsResult>;
54
+ };
55
+ export declare function useRevokeAccountAgentMutationOptions(): {
56
+ mutationKey: string[];
57
+ mutationFn: (grantId: string) => Promise<{
58
+ ok: true;
59
+ }>;
60
+ };
51
61
  export declare function useMfaQueryOptions(): {
52
62
  queryKey: readonly ["authkit", "account", "mfa"];
53
63
  queryFn: () => Promise<AccountMfaStatus>;
@@ -85,6 +85,20 @@ export function useRevokeAppMutationOptions() {
85
85
  mutationFn: (clientId) => client.account.apps.revoke(clientId),
86
86
  };
87
87
  }
88
+ export function useAccountAgentsQueryOptions() {
89
+ const client = useAuthkitClient();
90
+ return {
91
+ queryKey: authkitKeys.account.agents(),
92
+ queryFn: () => client.account.agents.list(),
93
+ };
94
+ }
95
+ export function useRevokeAccountAgentMutationOptions() {
96
+ const client = useAuthkitClient();
97
+ return {
98
+ mutationKey: ['authkit', 'account', 'agents', 'revoke'],
99
+ mutationFn: (grantId) => client.account.agents.revoke(grantId),
100
+ };
101
+ }
88
102
  export function useMfaQueryOptions() {
89
103
  const client = useAuthkitClient();
90
104
  return {
@@ -1,4 +1,4 @@
1
- import type { AdminClient, AdminClientListResult, AdminOrgDetail, AdminOrgEntry, AdminOrgInvitation, AdminOrgListResult, AdminOverview, AdminUser, AdminUserListResult, AuditListParams, AuditListResult, CreateClientInput, CreatedClientResult, CreateOrgInput, CreateRoleInput, CreateUserInput, ImpersonationPanel, KeysRotateInput, KeysRotateResult, KeysStatus, PersonalAgentConnectionsParams, PersonalAgentConnectionsResult, PersonalAgentRegistryInput, PersonalAgentRegistryResult, PersonalAgentsOverview, RegenerateSecretResult, RevokeSessionsResult, RoleCatalogEntry, RoleListResult, SettingEntry, SettingListResult, UpdateClientInput, UpdateOrgInput, UpdateRoleInput, UpdateUserInput, UserSessionsResult } from '../../client/types.js';
1
+ import type { AdminClient, AdminClientListResult, AdminOrgDetail, AdminOrgEntry, AdminOrgInvitation, AdminOrgListResult, AdminOverview, AdminUser, AdminUserListResult, AuditListParams, AuditListResult, CreateClientInput, CreatedClientResult, CreateOrgInput, CreateRoleInput, CreateUserInput, DeletedResult, ImpersonationPanel, KeysRotateInput, KeysRotateResult, KeysStatus, PersonalAgentConnectionsParams, PersonalAgentConnectionsResult, PersonalAgentRegistryInput, PersonalAgentRegistryResult, PersonalAgentsOverview, RegenerateSecretResult, ResetPasswordResult, RevokeSessionsResult, RoleCatalogEntry, RoleListResult, SettingEntry, SettingListResult, UpdateClientInput, UpdateOrgInput, UpdateRoleInput, UpdateUserInput, UserSessionsResult } from '../../client/types.js';
2
2
  export declare function useOverviewQueryOptions(): {
3
3
  queryKey: readonly ["authkit", "admin", "overview"];
4
4
  queryFn: () => Promise<AdminOverview>;
@@ -37,31 +37,19 @@ export declare function useUpdateUserMutationOptions(id: string): {
37
37
  };
38
38
  export declare function useDisableUserMutationOptions(id: string): {
39
39
  mutationKey: string[];
40
- mutationFn: () => Promise<{
41
- id: string;
42
- disabled: true;
43
- }>;
40
+ mutationFn: () => Promise<AdminUser>;
44
41
  };
45
42
  export declare function useEnableUserMutationOptions(id: string): {
46
43
  mutationKey: string[];
47
- mutationFn: () => Promise<{
48
- id: string;
49
- disabled: false;
50
- }>;
44
+ mutationFn: () => Promise<AdminUser>;
51
45
  };
52
46
  export declare function useResetPasswordMutationOptions(id: string): {
53
47
  mutationKey: string[];
54
- mutationFn: () => Promise<{
55
- id: string;
56
- sent: boolean;
57
- }>;
48
+ mutationFn: () => Promise<ResetPasswordResult>;
58
49
  };
59
50
  export declare function useDeleteUserMutationOptions(id: string): {
60
51
  mutationKey: string[];
61
- mutationFn: () => Promise<{
62
- id: string;
63
- deleted: boolean;
64
- }>;
52
+ mutationFn: () => Promise<DeletedResult>;
65
53
  };
66
54
  export declare function useRevokeUserSessionsMutationOptions(id: string): {
67
55
  mutationKey: string[];
@@ -94,10 +82,7 @@ export declare function useUpdateClientMutationOptions(id: string): {
94
82
  };
95
83
  export declare function useDeleteClientMutationOptions(id: string): {
96
84
  mutationKey: string[];
97
- mutationFn: () => Promise<{
98
- clientId: string;
99
- deleted: boolean;
100
- }>;
85
+ mutationFn: () => Promise<DeletedResult>;
101
86
  };
102
87
  export declare function useRegenerateClientSecretMutationOptions(id: string): {
103
88
  mutationKey: string[];
@@ -42,6 +42,7 @@ export declare const authkitKeys: {
42
42
  readonly security: () => readonly ['authkit', 'account', 'security'];
43
43
  readonly sessions: () => readonly ['authkit', 'account', 'sessions'];
44
44
  readonly apps: () => readonly ['authkit', 'account', 'apps'];
45
+ readonly agents: () => readonly ['authkit', 'account', 'agents'];
45
46
  readonly mfa: () => readonly ['authkit', 'account', 'mfa'];
46
47
  readonly passkeys: () => readonly ['authkit', 'account', 'passkeys'];
47
48
  readonly tokens: () => readonly ['authkit', 'account', 'tokens'];
@@ -26,6 +26,7 @@ export const authkitKeys = {
26
26
  security: () => ['authkit', 'account', 'security'],
27
27
  sessions: () => ['authkit', 'account', 'sessions'],
28
28
  apps: () => ['authkit', 'account', 'apps'],
29
+ agents: () => ['authkit', 'account', 'agents'],
29
30
  mfa: () => ['authkit', 'account', 'mfa'],
30
31
  passkeys: () => ['authkit', 'account', 'passkeys'],
31
32
  tokens: () => ['authkit', 'account', 'tokens'],
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@adonis-agora/authkit-react",
3
- "version": "0.26.0",
3
+ "version": "1.0.0-rc.1",
4
4
  "description": "Frontend ergonomics over AuthKit for AdonisJS + Inertia + React apps: a typed useAuth() hook, role-gating hooks and gating components.",
5
5
  "license": "MIT",
6
6
  "author": "dudousxd",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "https://github.com/DavideCarvalho/adonis-agora-authkit.git",
9
+ "url": "git+https://github.com/DavideCarvalho/adonis-agora-authkit.git",
10
10
  "directory": "packages/authkit-react"
11
11
  },
12
12
  "homepage": "https://davidecarvalho.github.io/agora/docs/authkit",
@@ -32,7 +32,8 @@
32
32
  "files": [
33
33
  "build",
34
34
  "styles.css",
35
- "skills"
35
+ "skills",
36
+ "CHANGELOG.md"
36
37
  ],
37
38
  "exports": {
38
39
  ".": "./build/index.js",
@@ -46,11 +47,11 @@
46
47
  "node": ">=24"
47
48
  },
48
49
  "peerDependencies": {
49
- "@inertiajs/react": "^3.7.0",
50
+ "@inertiajs/react": "^2.0.0 || ^3.0.0",
50
51
  "@simplewebauthn/browser": "^13.3.0 || ^14.0.0",
51
52
  "@tanstack/react-query": "^5.102.8",
52
- "react": "^19.2.8",
53
- "react-dom": "^19.2.8"
53
+ "react": "^19.0.0",
54
+ "react-dom": "^19.0.0"
54
55
  },
55
56
  "peerDependenciesMeta": {
56
57
  "@simplewebauthn/browser": {
@@ -58,17 +59,17 @@
58
59
  }
59
60
  },
60
61
  "dependencies": {
61
- "@adonis-agora/authkit-core": "0.10.1"
62
+ "@adonis-agora/authkit-core": "1.0.0-rc.0"
62
63
  },
63
64
  "devDependencies": {
64
65
  "@adonisjs/tsconfig": "2.0.0",
65
- "@inertiajs/react": "3.9.1",
66
+ "@inertiajs/react": "3.11.0",
66
67
  "@japa/assert": "4.2.0",
67
68
  "@japa/runner": "5.4.0",
68
- "@poppinss/ts-exec": "1.5.1",
69
+ "@poppinss/ts-exec": "1.5.2",
69
70
  "@tanstack/intent": "0.5.6",
70
- "@tanstack/react-query": "5.104.5",
71
- "@types/node": "26.6.5",
71
+ "@tanstack/react-query": "5.107.1",
72
+ "@types/node": "26.6.6",
72
73
  "@types/react": "19.3.0",
73
74
  "@types/react-dom": "19.3.0",
74
75
  "react": "19.3.1",
@@ -6,9 +6,10 @@ description: >-
6
6
  { user, globalRoles }), useAuth() semantics (never throws; AuthProvider context
7
7
  precedence), role helpers hasGlobalRole/hasAnyGlobalRole/hasAllGlobalRoles,
8
8
  Authenticated/Guest gating components with fallback, AuthkitProvider config
9
- ({ csrfToken, endpoints, idp }) with headless hooks (useSignIn, useSignOut,
10
- useProfile, useSessions, useAuthorizedApps) and ready components (SignInButton,
11
- UserButton, UserProfile, AuthorizedApps), and the idp:'external' degradation rule.
9
+ ({ csrfToken, endpoints, idp }) with headless hooks (useSignIn, useSignOut),
10
+ account data via query options (useMeQueryOptions, useAccountSessionsQueryOptions,
11
+ useAppsQueryOptions) and ready components (SignInButton, UserButton, UserProfile,
12
+ AuthorizedApps), and the idp:'external' degradation rule.
12
13
  Use when wiring the auth shared prop, gating UI by roles, adding sign-in/out
13
14
  buttons or account components, or debugging an always-unauthenticated React app.
14
15
  license: MIT
@@ -42,11 +43,11 @@ import { defineConfig } from '@adonisjs/inertia'
42
43
  export default defineConfig({
43
44
  sharedData: {
44
45
  authkit: async (ctx) => {
45
- const auth = ctx.authkit // your Authenticator instance
46
- const user = await auth.getUser() // same shape as identityToUser/resolveUser
46
+ const authkit = ctx.authkit // your Authenticator instance
47
+ const user = await authkit.getUser() // same shape as identityToUser/resolveUser
47
48
  return {
48
49
  user: user ?? null,
49
- globalRoles: auth.identity?.globalRoles ?? [],
50
+ globalRoles: authkit.identity?.globalRoles ?? [],
50
51
  }
51
52
  },
52
53
  },
@@ -118,28 +119,44 @@ Source: `packages/authkit-react/README.md` § 4.
118
119
 
119
120
  ### Pattern 3 — `AuthkitProvider` + ready components
120
121
 
121
- Wrap the app once to configure URLs/CSRF, then use headless hooks and prebuilt
122
- components that talk to the host-kit's JSON endpoints:
122
+ Wrap the app once to configure URLs/CSRF. The account components fetch through the
123
+ Account API, so they also need `QueryClientProvider` + `AuthkitClientProvider`.
124
+ `createAuthkitClient()` no longer reads `window.__AUTHKIT__`: pass `csrfToken`
125
+ (and `baseUrl` when using `client.admin.*`) via `AuthkitClientProvider opts`
126
+ — the `csrfToken` on `AuthkitProvider config` only covers `useCan`, not the
127
+ typed client's mutations:
123
128
 
124
129
  ```tsx
125
130
  import '@adonis-agora/authkit-react/styles.css'
131
+ import { QueryClientProvider } from '@tanstack/react-query'
126
132
  import {
133
+ AuthkitClientProvider,
127
134
  AuthkitProvider,
128
- useSignIn, useSignOut,
129
- UserButton, UserProfile, AuthorizedApps,
135
+ createAuthkitQueryClient,
136
+ AuthorizedApps,
137
+ UserButton,
138
+ UserProfile,
130
139
  } from '@adonis-agora/authkit-react'
131
140
 
132
- <AuthkitProvider config={{ csrfToken: page.props.csrfToken }}>
133
- <UserButton />
134
- <UserProfile />
135
- <AuthorizedApps />
136
- </AuthkitProvider>
141
+ const queryClient = createAuthkitQueryClient()
142
+
143
+ <QueryClientProvider client={queryClient}>
144
+ <AuthkitClientProvider opts={{ csrfToken: page.props.csrfToken }}>
145
+ <AuthkitProvider config={{ csrfToken: page.props.csrfToken }}>
146
+ <UserButton />
147
+ <UserProfile />
148
+ <AuthorizedApps />
149
+ </AuthkitProvider>
150
+ </AuthkitClientProvider>
151
+ </QueryClientProvider>
137
152
  ```
138
153
 
139
- Endpoint defaults point at real host-kit routes (`/auth/login`, `/account/logout`,
140
- `/account/security/profile`, `/account/apps`, …). In a *client-app* topology point
141
- them at local routes that redirect/proxy to the IdP; theming via CSS vars
142
- `--authkit-*`.
154
+ Admin screens also pass the admin base: `opts={{ baseUrl: '/admin/api', csrfToken }}`.
155
+ Account-only screens work with the default `/account/api` base and need no `baseUrl`.
156
+
157
+ Custom screens use the query options with `useQuery`/`useMutation`
158
+ (`useMeQueryOptions`, `useAccountSessionsQueryOptions`, `useAppsQueryOptions`,
159
+ `useAccountOrgsQueryOptions`, …). Theming via CSS vars `--authkit-*`.
143
160
 
144
161
  Source: `packages/authkit-react/README.md` § 5, `src/config.ts` (`DEFAULT_CONFIG`,
145
162
  `AuthkitConfig`).
@@ -172,10 +189,10 @@ export default defineConfig({ sharedData: {} })
172
189
  // Correct — share { user, globalRoles } under the `authkit` key
173
190
  sharedData: {
174
191
  authkit: async (ctx) => {
175
- const auth = ctx.authkit
192
+ const authkit = ctx.authkit
176
193
  return {
177
- user: (await auth.getUser()) ?? null,
178
- globalRoles: auth.identity?.globalRoles ?? [],
194
+ user: (await authkit.getUser()) ?? null,
195
+ globalRoles: authkit.identity?.globalRoles ?? [],
179
196
  }
180
197
  },
181
198
  }
@@ -1,16 +0,0 @@
1
- import { type ResourceState } from './use_resource.js';
2
- export interface AuthorizedApp {
3
- clientId: string;
4
- name?: string;
5
- logoUrl?: string;
6
- scopes?: string[];
7
- authorizedAt?: string;
8
- [key: string]: unknown;
9
- }
10
- export interface UseAuthorizedAppsResult extends ResourceState<AuthorizedApp[]> {
11
- actions: {
12
- refetch(): Promise<void>;
13
- revoke(clientId: string): Promise<void>;
14
- };
15
- }
16
- export declare function useAuthorizedApps(): UseAuthorizedAppsResult;
@@ -1,15 +0,0 @@
1
- import { useCallback } from 'react';
2
- import { useAuthkitConfig } from '../config.js';
3
- import { jsonRequest, useResource } from './use_resource.js';
4
- export function useAuthorizedApps() {
5
- const config = useAuthkitConfig();
6
- const { data, loading, error, refetch } = useResource(config.endpoints.apps, config.csrfToken);
7
- const revoke = useCallback(async (clientId) => {
8
- await jsonRequest(`${config.endpoints.apps}/${encodeURIComponent(clientId)}/revoke`, {
9
- method: 'POST',
10
- csrfToken: config.csrfToken,
11
- });
12
- await refetch();
13
- }, [config.endpoints.apps, config.csrfToken, refetch]);
14
- return { data, loading, error, actions: { refetch, revoke } };
15
- }
@@ -1,19 +0,0 @@
1
- import { type ResourceState } from './use_resource.js';
2
- export interface OrgInvitationEntry {
3
- id: string;
4
- organizationId: string;
5
- orgName: string;
6
- orgSlug: string;
7
- email: string;
8
- role: string;
9
- expiresAt: string;
10
- createdAt: string;
11
- [key: string]: unknown;
12
- }
13
- export interface UseOrgInvitationsResult extends ResourceState<OrgInvitationEntry[]> {
14
- actions: {
15
- refetch(): Promise<void>;
16
- accept(token: string): Promise<void>;
17
- };
18
- }
19
- export declare function useOrgInvitations(): UseOrgInvitationsResult;
@@ -1,20 +0,0 @@
1
- import { useCallback } from 'react';
2
- import { useAuthkitConfig } from '../config.js';
3
- import { jsonRequest, useResource } from './use_resource.js';
4
- export function useOrgInvitations() {
5
- const config = useAuthkitConfig();
6
- const { data, loading, error, refetch } = useResource(config.endpoints.orgInvitations, config.csrfToken);
7
- const accept = useCallback(async (token) => {
8
- await jsonRequest(`/account/orgs/invitations/${encodeURIComponent(token)}/accept`, {
9
- method: 'POST',
10
- csrfToken: config.csrfToken,
11
- });
12
- await refetch();
13
- }, [config.csrfToken, refetch]);
14
- return {
15
- data: data?.invitations ?? null,
16
- loading,
17
- error,
18
- actions: { refetch, accept },
19
- };
20
- }
@@ -1,23 +0,0 @@
1
- import { type ResourceState } from './use_resource.js';
2
- export interface OrgMemberEntry {
3
- accountId: string;
4
- email: string | null;
5
- role: string;
6
- joinedAt: string;
7
- }
8
- export interface ActiveOrgDetail {
9
- id: string;
10
- name: string;
11
- slug: string;
12
- logoUrl: string | null;
13
- role: string;
14
- canManage: boolean;
15
- members: OrgMemberEntry[];
16
- [key: string]: unknown;
17
- }
18
- export interface UseOrganizationResult extends ResourceState<ActiveOrgDetail> {
19
- actions: {
20
- refetch(): Promise<void>;
21
- };
22
- }
23
- export declare function useOrganization(orgId: string | null): UseOrganizationResult;
@@ -1,10 +0,0 @@
1
- import { useAuthkitConfig } from '../config.js';
2
- import { useResource } from './use_resource.js';
3
- export function useOrganization(orgId) {
4
- const config = useAuthkitConfig();
5
- const url = orgId
6
- ? `${config.endpoints.orgs.replace('/json', '')}/${encodeURIComponent(orgId)}/json`
7
- : '';
8
- const { data, loading, error, refetch } = useResource(url, config.csrfToken);
9
- return { data, loading: url ? loading : false, error, actions: { refetch } };
10
- }
@@ -1,18 +0,0 @@
1
- import { type ResourceState } from './use_resource.js';
2
- export interface OrgEntry {
3
- id: string;
4
- name: string;
5
- slug: string;
6
- logoUrl: string | null;
7
- role: string;
8
- isActive: boolean;
9
- [key: string]: unknown;
10
- }
11
- export interface UseOrganizationsResult extends ResourceState<OrgEntry[]> {
12
- activeOrgId: string | null;
13
- supported: boolean;
14
- actions: {
15
- refetch(): Promise<void>;
16
- };
17
- }
18
- export declare function useOrganizations(): UseOrganizationsResult;
@@ -1,14 +0,0 @@
1
- import { useAuthkitConfig } from '../config.js';
2
- import { useResource } from './use_resource.js';
3
- export function useOrganizations() {
4
- const config = useAuthkitConfig();
5
- const { data, loading, error, refetch } = useResource(config.endpoints.orgs, config.csrfToken);
6
- return {
7
- data: data?.orgs ?? null,
8
- loading,
9
- error,
10
- activeOrgId: data?.activeOrgId ?? null,
11
- supported: data?.supported ?? true,
12
- actions: { refetch },
13
- };
14
- }
@@ -1,13 +0,0 @@
1
- import type { AuthUser } from '../types.js';
2
- import { type ResourceState } from './use_resource.js';
3
- export interface ProfileUpdate {
4
- name?: string;
5
- avatarUrl?: string;
6
- [key: string]: unknown;
7
- }
8
- export interface UseProfileResult extends ResourceState<AuthUser> {
9
- actions: {
10
- update(data: ProfileUpdate): Promise<void>;
11
- };
12
- }
13
- export declare function useProfile(): UseProfileResult;