@adonis-agora/authkit-react 0.12.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/LICENSE +21 -0
- package/README.md +146 -0
- package/build/index.d.ts +68 -0
- package/build/index.js +36 -0
- package/build/src/authkit_provider.d.ts +13 -0
- package/build/src/authkit_provider.js +11 -0
- package/build/src/client/client.d.ts +172 -0
- package/build/src/client/client.js +218 -0
- package/build/src/client/context.d.ts +11 -0
- package/build/src/client/context.js +28 -0
- package/build/src/client/types.d.ts +425 -0
- package/build/src/client/types.js +1 -0
- package/build/src/components/authenticated.d.ts +11 -0
- package/build/src/components/authenticated.js +10 -0
- package/build/src/components/authorized_apps.d.ts +10 -0
- package/build/src/components/authorized_apps.js +34 -0
- package/build/src/components/avatar.d.ts +22 -0
- package/build/src/components/avatar.js +15 -0
- package/build/src/components/can.d.ts +10 -0
- package/build/src/components/can.js +19 -0
- package/build/src/components/key_rotation.d.ts +8 -0
- package/build/src/components/key_rotation.js +36 -0
- package/build/src/components/organization_profile.d.ts +10 -0
- package/build/src/components/organization_profile.js +94 -0
- package/build/src/components/organization_switcher.d.ts +9 -0
- package/build/src/components/organization_switcher.js +65 -0
- package/build/src/components/password_strength_meter.d.ts +11 -0
- package/build/src/components/password_strength_meter.js +39 -0
- package/build/src/components/sign_in_button.d.ts +297 -0
- package/build/src/components/sign_in_button.js +16 -0
- package/build/src/components/sign_out_button.d.ts +296 -0
- package/build/src/components/sign_out_button.js +16 -0
- package/build/src/components/user_button.d.ts +8 -0
- package/build/src/components/user_button.js +31 -0
- package/build/src/components/user_profile.d.ts +8 -0
- package/build/src/components/user_profile.js +35 -0
- package/build/src/config.d.ts +30 -0
- package/build/src/config.js +42 -0
- package/build/src/hooks/use_authorized_apps.d.ts +16 -0
- package/build/src/hooks/use_authorized_apps.js +15 -0
- package/build/src/hooks/use_org_invitations.d.ts +19 -0
- package/build/src/hooks/use_org_invitations.js +20 -0
- package/build/src/hooks/use_organization.d.ts +23 -0
- package/build/src/hooks/use_organization.js +8 -0
- package/build/src/hooks/use_organizations.d.ts +18 -0
- package/build/src/hooks/use_organizations.js +14 -0
- package/build/src/hooks/use_passkey_autofill.d.ts +8 -0
- package/build/src/hooks/use_passkey_autofill.js +76 -0
- package/build/src/hooks/use_password_strength.d.ts +11 -0
- package/build/src/hooks/use_password_strength.js +34 -0
- package/build/src/hooks/use_profile.d.ts +13 -0
- package/build/src/hooks/use_profile.js +28 -0
- package/build/src/hooks/use_resource.d.ts +11 -0
- package/build/src/hooks/use_resource.js +48 -0
- package/build/src/hooks/use_sessions.d.ts +16 -0
- package/build/src/hooks/use_sessions.js +15 -0
- package/build/src/hooks/use_sign_in.d.ts +6 -0
- package/build/src/hooks/use_sign_in.js +13 -0
- package/build/src/hooks/use_sign_out.d.ts +6 -0
- package/build/src/hooks/use_sign_out.js +11 -0
- package/build/src/hooks/use_switch_organization.d.ts +7 -0
- package/build/src/hooks/use_switch_organization.js +42 -0
- package/build/src/hooks/use_user.d.ts +6 -0
- package/build/src/hooks/use_user.js +5 -0
- package/build/src/provider.d.ts +16 -0
- package/build/src/provider.js +5 -0
- package/build/src/queries/account/index.d.ts +86 -0
- package/build/src/queries/account/index.js +150 -0
- package/build/src/queries/admin/index.d.ts +226 -0
- package/build/src/queries/admin/index.js +287 -0
- package/build/src/queries/keys.d.ts +50 -0
- package/build/src/queries/keys.js +34 -0
- package/build/src/roles.d.ts +7 -0
- package/build/src/roles.js +39 -0
- package/build/src/types.d.ts +27 -0
- package/build/src/types.js +1 -0
- package/build/src/use_auth.d.ts +2 -0
- package/build/src/use_auth.js +33 -0
- package/build/src/utils.d.ts +2 -0
- package/build/src/utils.js +18 -0
- package/package.json +68 -0
- package/styles.css +303 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface AuthorizedAppsProps {
|
|
2
|
+
className?: string;
|
|
3
|
+
revokeLabel?: string;
|
|
4
|
+
emptyLabel?: string;
|
|
5
|
+
}
|
|
6
|
+
declare function AuthorizedAppsInner({ className, revokeLabel, emptyLabel, }: AuthorizedAppsProps): import("react").DetailedReactHTMLElement<{
|
|
7
|
+
className: string;
|
|
8
|
+
}, HTMLElement>;
|
|
9
|
+
export declare function AuthorizedApps(props: Parameters<typeof AuthorizedAppsInner>[0]): import("react/jsx-runtime").JSX.Element | null;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createElement } from 'react';
|
|
3
|
+
import { useAuthkitConfig } from '../config.js';
|
|
4
|
+
import { useAuthorizedApps } from '../hooks/use_authorized_apps.js';
|
|
5
|
+
function AuthorizedAppsInner({ className, revokeLabel = 'Revogar', emptyLabel = 'Nenhum app autorizado.', }) {
|
|
6
|
+
const { data, loading, error, actions } = useAuthorizedApps();
|
|
7
|
+
if (loading && !data) {
|
|
8
|
+
return createElement('div', { className: 'authkit-apps__loading' }, 'Carregando…');
|
|
9
|
+
}
|
|
10
|
+
if (error) {
|
|
11
|
+
return createElement('p', { className: 'authkit-error', role: 'alert' }, error.message);
|
|
12
|
+
}
|
|
13
|
+
const apps = data ?? [];
|
|
14
|
+
if (apps.length === 0) {
|
|
15
|
+
return createElement('p', { className: 'authkit-apps__empty' }, emptyLabel);
|
|
16
|
+
}
|
|
17
|
+
return createElement('ul', { className: ['authkit-apps', className].filter(Boolean).join(' ') }, ...apps.map((app) => createElement('li', { key: app.clientId, className: 'authkit-apps__item' }, createElement('div', { className: 'authkit-apps__info' }, app.logoUrl
|
|
18
|
+
? createElement('img', {
|
|
19
|
+
className: 'authkit-apps__logo',
|
|
20
|
+
src: app.logoUrl,
|
|
21
|
+
alt: '',
|
|
22
|
+
})
|
|
23
|
+
: null, createElement('span', { className: 'authkit-apps__name' }, app.name ?? app.clientId)), createElement('button', {
|
|
24
|
+
type: 'button',
|
|
25
|
+
className: 'authkit-button authkit-button--danger',
|
|
26
|
+
onClick: () => void actions.revoke(app.clientId),
|
|
27
|
+
}, revokeLabel))));
|
|
28
|
+
}
|
|
29
|
+
export function AuthorizedApps(props) {
|
|
30
|
+
const { idp } = useAuthkitConfig();
|
|
31
|
+
if (idp === 'external')
|
|
32
|
+
return null;
|
|
33
|
+
return _jsx(AuthorizedAppsInner, { ...props });
|
|
34
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AuthUser } from '../types.js';
|
|
2
|
+
export interface AvatarProps {
|
|
3
|
+
user: Pick<AuthUser, 'name' | 'email' | 'avatarUrl'>;
|
|
4
|
+
size?: number;
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function Avatar({ user, size, className }: AvatarProps): import("react").DetailedReactHTMLElement<{
|
|
8
|
+
className: string;
|
|
9
|
+
src: string;
|
|
10
|
+
alt: string;
|
|
11
|
+
style: {
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
};
|
|
15
|
+
}, HTMLElement> | import("react").DetailedReactHTMLElement<{
|
|
16
|
+
className: string;
|
|
17
|
+
style: {
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
};
|
|
21
|
+
'aria-hidden': true;
|
|
22
|
+
}, HTMLElement>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createElement } from 'react';
|
|
2
|
+
import { deriveInitials } from '../utils.js';
|
|
3
|
+
export function Avatar({ user, size = 36, className }) {
|
|
4
|
+
const cls = ['authkit-avatar', className].filter(Boolean).join(' ');
|
|
5
|
+
const style = { width: size, height: size };
|
|
6
|
+
if (user.avatarUrl) {
|
|
7
|
+
return createElement('img', {
|
|
8
|
+
className: cls,
|
|
9
|
+
src: user.avatarUrl,
|
|
10
|
+
alt: user.name ?? user.email ?? '',
|
|
11
|
+
style,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
return createElement('span', { className: cls, style, 'aria-hidden': true }, deriveInitials(user.name, user.email));
|
|
15
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface CanProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
role?: string;
|
|
5
|
+
roles?: string[];
|
|
6
|
+
mode?: 'any' | 'all';
|
|
7
|
+
appRole?: boolean;
|
|
8
|
+
fallback?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export declare function Can({ children, role, roles, mode, appRole, fallback, }: CanProps): import("react").FunctionComponentElement<import("react").FragmentProps>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createElement, Fragment } from 'react';
|
|
2
|
+
import { useAuth } from '../use_auth.js';
|
|
3
|
+
import { hasAllAppRoles, hasAllGlobalRoles, hasAnyAppRole, hasAnyGlobalRole, hasAppRole, hasGlobalRole, } from '../roles.js';
|
|
4
|
+
export function Can({ children, role, roles, mode = 'any', appRole = false, fallback = null, }) {
|
|
5
|
+
const { user } = useAuth();
|
|
6
|
+
let allowed = false;
|
|
7
|
+
if (role !== undefined) {
|
|
8
|
+
allowed = appRole ? hasAppRole(user, role) : hasGlobalRole(user, role);
|
|
9
|
+
}
|
|
10
|
+
else if (roles !== undefined) {
|
|
11
|
+
if (appRole) {
|
|
12
|
+
allowed = mode === 'all' ? hasAllAppRoles(user, roles) : hasAnyAppRole(user, roles);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
allowed = mode === 'all' ? hasAllGlobalRoles(user, roles) : hasAnyGlobalRole(user, roles);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return createElement(Fragment, null, allowed ? children : fallback);
|
|
19
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface KeyRotationProps {
|
|
2
|
+
className?: string;
|
|
3
|
+
}
|
|
4
|
+
declare function KeyRotationInner({ className }: KeyRotationProps): import("react").DetailedReactHTMLElement<{
|
|
5
|
+
className: string;
|
|
6
|
+
}, HTMLElement>;
|
|
7
|
+
export declare function KeyRotation(props: Parameters<typeof KeyRotationInner>[0]): import("react").FunctionComponentElement<KeyRotationProps>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { createElement, useState } from 'react';
|
|
2
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { useKeysQueryOptions, useRotateKeysMutationOptions } from '../queries/admin/index.js';
|
|
4
|
+
import { authkitKeys } from '../queries/keys.js';
|
|
5
|
+
function KeyRotationInner({ className }) {
|
|
6
|
+
const qc = useQueryClient();
|
|
7
|
+
const status = useQuery(useKeysQueryOptions());
|
|
8
|
+
const rotate = useMutation({
|
|
9
|
+
...useRotateKeysMutationOptions(),
|
|
10
|
+
onSuccess: () => qc.invalidateQueries({ queryKey: authkitKeys.admin.keys() }),
|
|
11
|
+
});
|
|
12
|
+
const [retire, setRetire] = useState(false);
|
|
13
|
+
if (status.isLoading && !status.data) {
|
|
14
|
+
return createElement('div', { className: 'authkit-keys__loading' }, 'Carregando…');
|
|
15
|
+
}
|
|
16
|
+
if (status.error) {
|
|
17
|
+
return createElement('p', { className: 'authkit-error', role: 'alert' }, status.error.message);
|
|
18
|
+
}
|
|
19
|
+
const data = status.data;
|
|
20
|
+
const p = data.policy;
|
|
21
|
+
return createElement('div', { className: ['authkit-card', 'authkit-keys', className].filter(Boolean).join(' ') }, createElement('h3', { className: 'authkit-keys__title' }, 'Chave de assinatura'), createElement('dl', { className: 'authkit-keys__stats' }, createElement('dt', null, 'Idade'), createElement('dd', null, `${data.ageDays} dia(s)`), createElement('dt', null, 'Rotação automática'), createElement('dd', null, p.enabled ? `a cada ${p.maxAgeDays}d (mantém ${p.keep})` : 'desligada'), createElement('dt', null, 'Próxima rotação'), createElement('dd', null, data.nextRotationInDays === null ? '—' : `em ~${data.nextRotationInDays} dia(s)`)), createElement('label', { className: 'authkit-keys__retire' }, createElement('input', {
|
|
22
|
+
type: 'checkbox',
|
|
23
|
+
checked: retire,
|
|
24
|
+
onChange: (e) => setRetire(e.target.checked),
|
|
25
|
+
}), ' Aposentar as chaves antigas de imediato'), rotate.error
|
|
26
|
+
? createElement('p', { className: 'authkit-error', role: 'alert' }, rotate.error.message)
|
|
27
|
+
: null, createElement('button', {
|
|
28
|
+
type: 'button',
|
|
29
|
+
className: 'authkit-button authkit-button--primary',
|
|
30
|
+
disabled: rotate.isPending,
|
|
31
|
+
onClick: () => rotate.mutate(retire ? { retire: true } : undefined),
|
|
32
|
+
}, rotate.isPending ? 'Rotacionando…' : 'Rotacionar agora'));
|
|
33
|
+
}
|
|
34
|
+
export function KeyRotation(props) {
|
|
35
|
+
return createElement(KeyRotationInner, props);
|
|
36
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface OrganizationProfileProps {
|
|
2
|
+
inviteLabel?: string;
|
|
3
|
+
leaveLabel?: string;
|
|
4
|
+
className?: string;
|
|
5
|
+
}
|
|
6
|
+
declare function OrganizationProfileInner({ inviteLabel, leaveLabel, className, }: OrganizationProfileProps): import("react").DetailedReactHTMLElement<{
|
|
7
|
+
className: string;
|
|
8
|
+
}, HTMLElement> | null;
|
|
9
|
+
export declare function OrganizationProfile(props: Parameters<typeof OrganizationProfileInner>[0]): import("react/jsx-runtime").JSX.Element | null;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createElement, useState } from 'react';
|
|
3
|
+
import { useOrganizations } from '../hooks/use_organizations.js';
|
|
4
|
+
import { useOrganization } from '../hooks/use_organization.js';
|
|
5
|
+
import { useAuth } from '../use_auth.js';
|
|
6
|
+
import { useAuthkitConfig } from '../config.js';
|
|
7
|
+
import { jsonRequest } from '../hooks/use_resource.js';
|
|
8
|
+
function OrganizationProfileInner({ inviteLabel = 'Convidar membro', leaveLabel = 'Sair da organização', className, }) {
|
|
9
|
+
const { isAuthenticated } = useAuth();
|
|
10
|
+
const config = useAuthkitConfig();
|
|
11
|
+
const { activeOrgId, actions: orgListActions } = useOrganizations();
|
|
12
|
+
const { data: org, loading, error, actions } = useOrganization(activeOrgId);
|
|
13
|
+
const [inviteEmail, setInviteEmail] = useState('');
|
|
14
|
+
const [inviteRole, setInviteRole] = useState('member');
|
|
15
|
+
const [inviteLoading, setInviteLoading] = useState(false);
|
|
16
|
+
const [inviteError, setInviteError] = useState(null);
|
|
17
|
+
if (!isAuthenticated || !activeOrgId)
|
|
18
|
+
return null;
|
|
19
|
+
if (loading)
|
|
20
|
+
return createElement('div', { className: 'authkit-org-profile__loading' }, 'Carregando…');
|
|
21
|
+
if (error)
|
|
22
|
+
return createElement('div', { className: 'authkit-error' }, error.message);
|
|
23
|
+
if (!org)
|
|
24
|
+
return null;
|
|
25
|
+
const base = config.endpoints.orgs.replace('/json', '');
|
|
26
|
+
const handleInvite = async (e) => {
|
|
27
|
+
e.preventDefault();
|
|
28
|
+
if (!inviteEmail.trim())
|
|
29
|
+
return;
|
|
30
|
+
setInviteLoading(true);
|
|
31
|
+
setInviteError(null);
|
|
32
|
+
try {
|
|
33
|
+
await jsonRequest(`${base}/${encodeURIComponent(activeOrgId)}/invite`, {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
body: JSON.stringify({ email: inviteEmail.trim(), role: inviteRole }),
|
|
36
|
+
csrfToken: config.csrfToken,
|
|
37
|
+
});
|
|
38
|
+
setInviteEmail('');
|
|
39
|
+
await actions.refetch();
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
setInviteError(err);
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
setInviteLoading(false);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const handleLeave = async () => {
|
|
49
|
+
try {
|
|
50
|
+
await jsonRequest(`${base}/${encodeURIComponent(activeOrgId)}/leave`, {
|
|
51
|
+
method: 'POST',
|
|
52
|
+
csrfToken: config.csrfToken,
|
|
53
|
+
});
|
|
54
|
+
await orgListActions.refetch();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const memberList = createElement('div', { className: 'authkit-org-profile__members' }, createElement('h3', { className: 'authkit-org-profile__section-title' }, 'Membros'), ...(org.members.length === 0
|
|
60
|
+
? [createElement('p', { className: 'authkit-org-profile__empty' }, 'Nenhum membro.')]
|
|
61
|
+
: org.members.map((m) => createElement('div', { key: m.accountId, className: 'authkit-org-profile__member' }, createElement('div', { className: 'authkit-org-profile__member-info' }, createElement('span', { className: 'authkit-org-profile__member-email' }, m.email ?? m.accountId), createElement('span', { className: 'authkit-org-profile__member-role' }, m.role))))));
|
|
62
|
+
const inviteForm = org.canManage
|
|
63
|
+
? createElement('form', { className: 'authkit-org-profile__invite-form', onSubmit: handleInvite }, createElement('h3', { className: 'authkit-org-profile__section-title' }, inviteLabel), createElement('input', {
|
|
64
|
+
className: 'authkit-input',
|
|
65
|
+
type: 'email',
|
|
66
|
+
placeholder: 'Email',
|
|
67
|
+
value: inviteEmail,
|
|
68
|
+
onChange: (e) => setInviteEmail(e.target.value),
|
|
69
|
+
}), createElement('input', {
|
|
70
|
+
className: 'authkit-input',
|
|
71
|
+
placeholder: 'Papel (ex: member)',
|
|
72
|
+
value: inviteRole,
|
|
73
|
+
onChange: (e) => setInviteRole(e.target.value),
|
|
74
|
+
}), inviteError
|
|
75
|
+
? createElement('p', { className: 'authkit-error', role: 'alert' }, inviteError.message)
|
|
76
|
+
: null, createElement('button', {
|
|
77
|
+
type: 'submit',
|
|
78
|
+
className: 'authkit-button authkit-button--primary',
|
|
79
|
+
disabled: inviteLoading,
|
|
80
|
+
}, inviteLoading ? 'Enviando…' : inviteLabel))
|
|
81
|
+
: null;
|
|
82
|
+
const leaveButton = createElement('button', {
|
|
83
|
+
type: 'button',
|
|
84
|
+
className: 'authkit-button authkit-button--danger',
|
|
85
|
+
onClick: handleLeave,
|
|
86
|
+
}, leaveLabel);
|
|
87
|
+
return createElement('div', { className: ['authkit-card', 'authkit-org-profile', className].filter(Boolean).join(' ') }, createElement('div', { className: 'authkit-org-profile__header' }, createElement('div', { className: 'authkit-org-profile__name' }, org.name), createElement('div', { className: 'authkit-org-profile__slug' }, org.slug)), memberList, inviteForm, leaveButton);
|
|
88
|
+
}
|
|
89
|
+
export function OrganizationProfile(props) {
|
|
90
|
+
const { idp } = useAuthkitConfig();
|
|
91
|
+
if (idp === 'external')
|
|
92
|
+
return null;
|
|
93
|
+
return _jsx(OrganizationProfileInner, { ...props });
|
|
94
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface OrganizationSwitcherProps {
|
|
2
|
+
personalAccountLabel?: string;
|
|
3
|
+
className?: string;
|
|
4
|
+
}
|
|
5
|
+
declare function OrganizationSwitcherInner({ personalAccountLabel, className, }: OrganizationSwitcherProps): import("react").DetailedReactHTMLElement<{
|
|
6
|
+
className: string;
|
|
7
|
+
}, HTMLElement> | null;
|
|
8
|
+
export declare function OrganizationSwitcher(props: Parameters<typeof OrganizationSwitcherInner>[0]): import("react/jsx-runtime").JSX.Element | null;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { createElement, useState } from 'react';
|
|
3
|
+
import { useAuthkitConfig } from '../config.js';
|
|
4
|
+
import { useOrganizations } from '../hooks/use_organizations.js';
|
|
5
|
+
import { useSwitchOrganization } from '../hooks/use_switch_organization.js';
|
|
6
|
+
import { useAuth } from '../use_auth.js';
|
|
7
|
+
function OrganizationSwitcherInner({ personalAccountLabel = 'Conta pessoal', className, }) {
|
|
8
|
+
const { isAuthenticated } = useAuth();
|
|
9
|
+
const { data: orgs, activeOrgId, supported } = useOrganizations();
|
|
10
|
+
const { activate, deactivate, loading: switching } = useSwitchOrganization();
|
|
11
|
+
const [open, setOpen] = useState(false);
|
|
12
|
+
if (!isAuthenticated || !supported)
|
|
13
|
+
return null;
|
|
14
|
+
const activeOrg = orgs?.find((o) => o.id === activeOrgId) ?? null;
|
|
15
|
+
const label = activeOrg ? activeOrg.name : personalAccountLabel;
|
|
16
|
+
const trigger = createElement('button', {
|
|
17
|
+
type: 'button',
|
|
18
|
+
className: 'authkit-orgswitcher__trigger',
|
|
19
|
+
'aria-haspopup': 'listbox',
|
|
20
|
+
'aria-expanded': open,
|
|
21
|
+
disabled: switching,
|
|
22
|
+
onClick: () => setOpen((v) => !v),
|
|
23
|
+
}, createElement('span', { className: 'authkit-orgswitcher__label' }, label), createElement('span', { className: 'authkit-orgswitcher__chevron', 'aria-hidden': 'true' }, '▾'));
|
|
24
|
+
const menu = open
|
|
25
|
+
? createElement('div', { className: 'authkit-orgswitcher__menu', role: 'listbox' }, createElement('button', {
|
|
26
|
+
type: 'button',
|
|
27
|
+
className: [
|
|
28
|
+
'authkit-orgswitcher__item',
|
|
29
|
+
!activeOrgId ? 'authkit-orgswitcher__item--active' : '',
|
|
30
|
+
]
|
|
31
|
+
.filter(Boolean)
|
|
32
|
+
.join(' '),
|
|
33
|
+
role: 'option',
|
|
34
|
+
'aria-selected': !activeOrgId,
|
|
35
|
+
onClick: async () => {
|
|
36
|
+
setOpen(false);
|
|
37
|
+
if (activeOrgId)
|
|
38
|
+
await deactivate();
|
|
39
|
+
},
|
|
40
|
+
}, createElement('span', { className: 'authkit-orgswitcher__item-name' }, personalAccountLabel)), ...(orgs ?? []).map((org) => createElement('button', {
|
|
41
|
+
key: org.id,
|
|
42
|
+
type: 'button',
|
|
43
|
+
className: [
|
|
44
|
+
'authkit-orgswitcher__item',
|
|
45
|
+
org.isActive ? 'authkit-orgswitcher__item--active' : '',
|
|
46
|
+
]
|
|
47
|
+
.filter(Boolean)
|
|
48
|
+
.join(' '),
|
|
49
|
+
role: 'option',
|
|
50
|
+
'aria-selected': org.isActive,
|
|
51
|
+
onClick: async () => {
|
|
52
|
+
setOpen(false);
|
|
53
|
+
if (!org.isActive)
|
|
54
|
+
await activate(org.id);
|
|
55
|
+
},
|
|
56
|
+
}, createElement('span', { className: 'authkit-orgswitcher__item-name' }, org.name), createElement('span', { className: 'authkit-orgswitcher__item-role' }, org.role))))
|
|
57
|
+
: null;
|
|
58
|
+
return createElement('div', { className: ['authkit-orgswitcher', className].filter(Boolean).join(' ') }, trigger, menu);
|
|
59
|
+
}
|
|
60
|
+
export function OrganizationSwitcher(props) {
|
|
61
|
+
const { idp } = useAuthkitConfig();
|
|
62
|
+
if (idp === 'external')
|
|
63
|
+
return null;
|
|
64
|
+
return _jsx(OrganizationSwitcherInner, { ...props });
|
|
65
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type PasswordScorer } from '../hooks/use_password_strength.js';
|
|
2
|
+
export interface PasswordStrengthMeterProps {
|
|
3
|
+
password: string;
|
|
4
|
+
scorer?: PasswordScorer;
|
|
5
|
+
showFeedback?: boolean;
|
|
6
|
+
labels?: [string, string, string, string, string];
|
|
7
|
+
className?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function PasswordStrengthMeter({ password, scorer, showFeedback, labels, className, }: PasswordStrengthMeterProps): import("react").DetailedReactHTMLElement<{
|
|
10
|
+
className: string;
|
|
11
|
+
}, HTMLElement>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createElement } from 'react';
|
|
2
|
+
import { usePasswordStrength, } from '../hooks/use_password_strength.js';
|
|
3
|
+
const DEFAULT_LABELS = [
|
|
4
|
+
'Very weak',
|
|
5
|
+
'Weak',
|
|
6
|
+
'Fair',
|
|
7
|
+
'Good',
|
|
8
|
+
'Strong',
|
|
9
|
+
];
|
|
10
|
+
export function PasswordStrengthMeter({ password, scorer, showFeedback = true, labels = DEFAULT_LABELS, className, }) {
|
|
11
|
+
const { score, feedback } = usePasswordStrength(password, { scorer });
|
|
12
|
+
const cls = ['authkit-strength', className].filter(Boolean).join(' ');
|
|
13
|
+
const segments = [0, 1, 2, 3].map((i) => createElement('span', {
|
|
14
|
+
key: i,
|
|
15
|
+
className: [
|
|
16
|
+
'authkit-strength__segment',
|
|
17
|
+
i < score ? 'authkit-strength__segment--filled' : '',
|
|
18
|
+
]
|
|
19
|
+
.filter(Boolean)
|
|
20
|
+
.join(' '),
|
|
21
|
+
}));
|
|
22
|
+
const children = [
|
|
23
|
+
createElement('div', {
|
|
24
|
+
key: 'bar',
|
|
25
|
+
className: 'authkit-strength__bar',
|
|
26
|
+
role: 'meter',
|
|
27
|
+
'aria-valuemin': 0,
|
|
28
|
+
'aria-valuemax': 4,
|
|
29
|
+
'aria-valuenow': score,
|
|
30
|
+
'aria-label': labels[score],
|
|
31
|
+
'data-score': score,
|
|
32
|
+
}, segments),
|
|
33
|
+
createElement('span', { key: 'label', className: 'authkit-strength__label' }, labels[score]),
|
|
34
|
+
];
|
|
35
|
+
if (showFeedback && feedback && feedback.length > 0) {
|
|
36
|
+
children.push(createElement('ul', { key: 'feedback', className: 'authkit-strength__feedback' }, feedback.map((tip, i) => createElement('li', { key: i }, tip))));
|
|
37
|
+
}
|
|
38
|
+
return createElement('div', { className: cls }, children);
|
|
39
|
+
}
|