@authhero/react-admin 0.10.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/.eslintrc.js +21 -0
- package/.vercelignore +4 -0
- package/CHANGELOG.md +56 -0
- package/LICENSE +21 -0
- package/README.md +50 -0
- package/index.html +125 -0
- package/package.json +61 -0
- package/prettier.config.js +1 -0
- package/public/favicon.ico +0 -0
- package/public/manifest.json +15 -0
- package/src/App.spec.tsx +42 -0
- package/src/App.tsx +232 -0
- package/src/AuthCallback.tsx +138 -0
- package/src/Layout.tsx +12 -0
- package/src/TenantsApp.tsx +115 -0
- package/src/auth0DataProvider.ts +1242 -0
- package/src/authProvider.ts +521 -0
- package/src/components/CertificateErrorDialog.tsx +116 -0
- package/src/components/DomainSelector.tsx +401 -0
- package/src/components/TenantAppBar.tsx +83 -0
- package/src/components/TenantLayout.tsx +25 -0
- package/src/components/TenantsAppBar.tsx +21 -0
- package/src/components/TenantsLayout.tsx +28 -0
- package/src/components/activity/ActivityDashboard.tsx +381 -0
- package/src/components/activity/index.ts +1 -0
- package/src/components/branding/BrandingList.tsx +0 -0
- package/src/components/branding/BrandingShow.tsx +0 -0
- package/src/components/branding/ThemesTab.tsx +286 -0
- package/src/components/branding/edit.tsx +149 -0
- package/src/components/branding/hooks/useThemesData.ts +123 -0
- package/src/components/branding/index.ts +2 -0
- package/src/components/branding/list.tsx +12 -0
- package/src/components/clients/create.tsx +12 -0
- package/src/components/clients/edit.tsx +1285 -0
- package/src/components/clients/index.ts +3 -0
- package/src/components/clients/list.tsx +37 -0
- package/src/components/common/DateAgo.tsx +6 -0
- package/src/components/common/JsonOutput.tsx +26 -0
- package/src/components/common/index.ts +1 -0
- package/src/components/connections/create.tsx +35 -0
- package/src/components/connections/edit.tsx +212 -0
- package/src/components/connections/index.ts +3 -0
- package/src/components/connections/list.tsx +15 -0
- package/src/components/custom-domains/create.tsx +26 -0
- package/src/components/custom-domains/edit.tsx +101 -0
- package/src/components/custom-domains/index.ts +3 -0
- package/src/components/custom-domains/list.tsx +16 -0
- package/src/components/flows/create.tsx +30 -0
- package/src/components/flows/edit.tsx +238 -0
- package/src/components/flows/index.ts +3 -0
- package/src/components/flows/list.tsx +15 -0
- package/src/components/forms/FlowEditor.tsx +1363 -0
- package/src/components/forms/NodeEditor.tsx +1119 -0
- package/src/components/forms/RichTextEditor.tsx +145 -0
- package/src/components/forms/create.tsx +30 -0
- package/src/components/forms/edit.tsx +256 -0
- package/src/components/forms/index.ts +3 -0
- package/src/components/forms/list.tsx +16 -0
- package/src/components/hooks/create.tsx +96 -0
- package/src/components/hooks/edit.tsx +114 -0
- package/src/components/hooks/index.ts +3 -0
- package/src/components/hooks/list.tsx +17 -0
- package/src/components/listActions/PostListActions.tsx +10 -0
- package/src/components/logs/LogIcon.tsx +32 -0
- package/src/components/logs/LogShow.tsx +82 -0
- package/src/components/logs/LogType.tsx +38 -0
- package/src/components/logs/index.ts +4 -0
- package/src/components/logs/list.tsx +41 -0
- package/src/components/organizations/create.tsx +13 -0
- package/src/components/organizations/edit.tsx +682 -0
- package/src/components/organizations/index.ts +3 -0
- package/src/components/organizations/list.tsx +21 -0
- package/src/components/resource-servers/create.tsx +87 -0
- package/src/components/resource-servers/edit.tsx +121 -0
- package/src/components/resource-servers/index.ts +3 -0
- package/src/components/resource-servers/list.tsx +47 -0
- package/src/components/roles/create.tsx +12 -0
- package/src/components/roles/edit.tsx +426 -0
- package/src/components/roles/index.ts +3 -0
- package/src/components/roles/list.tsx +24 -0
- package/src/components/sessions/edit.tsx +101 -0
- package/src/components/sessions/index.ts +3 -0
- package/src/components/sessions/list.tsx +20 -0
- package/src/components/sessions/show.tsx +113 -0
- package/src/components/settings/edit.tsx +236 -0
- package/src/components/settings/index.ts +2 -0
- package/src/components/settings/list.tsx +14 -0
- package/src/components/tenants/create.tsx +20 -0
- package/src/components/tenants/edit.tsx +54 -0
- package/src/components/tenants/index.ts +2 -0
- package/src/components/tenants/list.tsx +67 -0
- package/src/components/themes/edit.tsx +200 -0
- package/src/components/themes/index.ts +2 -0
- package/src/components/themes/list.tsx +12 -0
- package/src/components/users/create.tsx +144 -0
- package/src/components/users/edit.tsx +1711 -0
- package/src/components/users/index.ts +3 -0
- package/src/components/users/list.tsx +35 -0
- package/src/data.json +121 -0
- package/src/dataProvider.ts +97 -0
- package/src/index.tsx +106 -0
- package/src/lib/logs.ts +21 -0
- package/src/types/reactflow.d.ts +86 -0
- package/src/utils/domainUtils.ts +169 -0
- package/src/utils/tokenUtils.ts +75 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +37 -0
- package/tsconfig.node.json +10 -0
- package/vercel.json +17 -0
- package/vite.config.ts +30 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Edit,
|
|
3
|
+
SimpleForm,
|
|
4
|
+
TextInput,
|
|
5
|
+
required,
|
|
6
|
+
ArrayInput,
|
|
7
|
+
SimpleFormIterator,
|
|
8
|
+
SelectInput,
|
|
9
|
+
FormDataConsumer,
|
|
10
|
+
DateField,
|
|
11
|
+
Labeled,
|
|
12
|
+
BooleanInput,
|
|
13
|
+
} from "react-admin";
|
|
14
|
+
import { Typography, Box, Alert } from "@mui/material";
|
|
15
|
+
|
|
16
|
+
const ACTION_TYPE_CHOICES = [
|
|
17
|
+
{ id: "REDIRECT", name: "Redirect" },
|
|
18
|
+
{ id: "AUTH0", name: "Auth0" },
|
|
19
|
+
{ id: "EMAIL", name: "Email" },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
const AUTH0_ACTION_CHOICES = [
|
|
23
|
+
{ id: "UPDATE_USER", name: "Update User" },
|
|
24
|
+
{ id: "CREATE_USER", name: "Create User" },
|
|
25
|
+
{ id: "GET_USER", name: "Get User" },
|
|
26
|
+
{ id: "SEND_REQUEST", name: "Send Request" },
|
|
27
|
+
{ id: "SEND_EMAIL", name: "Send Email" },
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const EMAIL_ACTION_CHOICES = [{ id: "VERIFY_EMAIL", name: "Verify Email" }];
|
|
31
|
+
|
|
32
|
+
const REDIRECT_TARGET_CHOICES = [
|
|
33
|
+
{
|
|
34
|
+
id: "change-email",
|
|
35
|
+
name: "Change Email",
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: "account",
|
|
39
|
+
name: "Account Settings",
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "custom",
|
|
43
|
+
name: "Custom URL",
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
// Generate Auth0-style action IDs like "verify_email_address_YrOx"
|
|
48
|
+
const generateActionId = (type: string, action?: string) => {
|
|
49
|
+
const suffix = Math.random().toString(36).substring(2, 6);
|
|
50
|
+
|
|
51
|
+
if (type === "REDIRECT") {
|
|
52
|
+
return `redirect_user_${suffix}`;
|
|
53
|
+
}
|
|
54
|
+
if (type === "EMAIL" && action === "VERIFY_EMAIL") {
|
|
55
|
+
return `verify_email_address_${suffix}`;
|
|
56
|
+
}
|
|
57
|
+
if (type === "AUTH0") {
|
|
58
|
+
const actionName = (action || "action").toLowerCase();
|
|
59
|
+
return `${actionName}_${suffix}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return `action_${suffix}`;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Parse function to extract params into form fields when loading
|
|
66
|
+
const parseFlowData = (data: Record<string, unknown>) => {
|
|
67
|
+
if (data.actions && Array.isArray(data.actions)) {
|
|
68
|
+
data.actions = data.actions.map((action: Record<string, unknown>) => {
|
|
69
|
+
const parsed = { ...action };
|
|
70
|
+
|
|
71
|
+
// Extract REDIRECT params into form fields
|
|
72
|
+
if (parsed.type === "REDIRECT" && parsed.params) {
|
|
73
|
+
const params = parsed.params as Record<string, unknown>;
|
|
74
|
+
if (params.target) {
|
|
75
|
+
parsed.redirect_target = params.target;
|
|
76
|
+
}
|
|
77
|
+
if (params.custom_url) {
|
|
78
|
+
parsed.redirect_custom_url = params.custom_url;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return parsed;
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
return data;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export const FlowEdit = () => {
|
|
89
|
+
return (
|
|
90
|
+
<Edit
|
|
91
|
+
queryOptions={{
|
|
92
|
+
select: (data) => ({
|
|
93
|
+
data: parseFlowData(data.data as Record<string, unknown>),
|
|
94
|
+
}),
|
|
95
|
+
}}
|
|
96
|
+
transform={(data: Record<string, unknown>) => {
|
|
97
|
+
// Transform actions to include required fields
|
|
98
|
+
if (data.actions && Array.isArray(data.actions)) {
|
|
99
|
+
data.actions = data.actions.map((action: Record<string, unknown>) => {
|
|
100
|
+
const transformed = { ...action };
|
|
101
|
+
|
|
102
|
+
// Remove any nested actions array (form bug workaround)
|
|
103
|
+
delete transformed.actions;
|
|
104
|
+
|
|
105
|
+
// Add action type for REDIRECT
|
|
106
|
+
if (transformed.type === "REDIRECT") {
|
|
107
|
+
transformed.action = "REDIRECT_USER";
|
|
108
|
+
// Build params with target and optional custom_url
|
|
109
|
+
// Prioritize form fields over existing params (user edits should take effect)
|
|
110
|
+
const target =
|
|
111
|
+
(transformed.redirect_target as string) ||
|
|
112
|
+
(transformed.params as Record<string, unknown>)?.target ||
|
|
113
|
+
"change-email";
|
|
114
|
+
const params: Record<string, unknown> = { target };
|
|
115
|
+
|
|
116
|
+
// Include custom_url when target is "custom"
|
|
117
|
+
if (target === "custom") {
|
|
118
|
+
const customUrl =
|
|
119
|
+
(transformed.redirect_custom_url as string) ||
|
|
120
|
+
(transformed.params as Record<string, unknown>)?.custom_url;
|
|
121
|
+
if (customUrl) {
|
|
122
|
+
params.custom_url = customUrl;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
transformed.params = params;
|
|
127
|
+
// Clean up temporary fields
|
|
128
|
+
delete transformed.redirect_target;
|
|
129
|
+
delete transformed.redirect_custom_url;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Auto-generate ID if not provided (Auth0-style)
|
|
133
|
+
if (!transformed.id) {
|
|
134
|
+
transformed.id = generateActionId(
|
|
135
|
+
transformed.type as string,
|
|
136
|
+
transformed.action as string | undefined,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return transformed;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return data;
|
|
144
|
+
}}
|
|
145
|
+
>
|
|
146
|
+
<SimpleForm>
|
|
147
|
+
<TextInput source="name" validate={[required()]} fullWidth />
|
|
148
|
+
|
|
149
|
+
<Box sx={{ mt: 3, mb: 2 }}>
|
|
150
|
+
<Typography variant="h6">Actions</Typography>
|
|
151
|
+
<Typography variant="body2" color="text.secondary">
|
|
152
|
+
Define the sequence of actions to execute in this flow.
|
|
153
|
+
</Typography>
|
|
154
|
+
</Box>
|
|
155
|
+
|
|
156
|
+
<Alert severity="info" sx={{ mb: 2 }}>
|
|
157
|
+
<strong>Quick Tip:</strong> To redirect users to the change email
|
|
158
|
+
page, add a REDIRECT action with target "Change Email".
|
|
159
|
+
</Alert>
|
|
160
|
+
|
|
161
|
+
<ArrayInput source="actions">
|
|
162
|
+
<SimpleFormIterator inline>
|
|
163
|
+
<SelectInput
|
|
164
|
+
source="type"
|
|
165
|
+
label="Type"
|
|
166
|
+
choices={ACTION_TYPE_CHOICES}
|
|
167
|
+
validate={[required()]}
|
|
168
|
+
defaultValue="REDIRECT"
|
|
169
|
+
/>
|
|
170
|
+
|
|
171
|
+
<FormDataConsumer>
|
|
172
|
+
{({ scopedFormData }) => {
|
|
173
|
+
if (scopedFormData?.type === "AUTH0") {
|
|
174
|
+
return (
|
|
175
|
+
<SelectInput
|
|
176
|
+
source="action"
|
|
177
|
+
label="Action"
|
|
178
|
+
choices={AUTH0_ACTION_CHOICES}
|
|
179
|
+
validate={[required()]}
|
|
180
|
+
/>
|
|
181
|
+
);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (scopedFormData?.type === "EMAIL") {
|
|
185
|
+
return (
|
|
186
|
+
<SelectInput
|
|
187
|
+
source="action"
|
|
188
|
+
label="Action"
|
|
189
|
+
choices={EMAIL_ACTION_CHOICES}
|
|
190
|
+
validate={[required()]}
|
|
191
|
+
/>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (scopedFormData?.type === "REDIRECT") {
|
|
196
|
+
return (
|
|
197
|
+
<Box sx={{ display: "flex", gap: 2, flexWrap: "wrap" }}>
|
|
198
|
+
<SelectInput
|
|
199
|
+
source="redirect_target"
|
|
200
|
+
label="Redirect To"
|
|
201
|
+
choices={REDIRECT_TARGET_CHOICES}
|
|
202
|
+
validate={[required()]}
|
|
203
|
+
helperText="Select where to redirect the user"
|
|
204
|
+
defaultValue="change-email"
|
|
205
|
+
/>
|
|
206
|
+
{scopedFormData?.redirect_target === "custom" && (
|
|
207
|
+
<TextInput
|
|
208
|
+
source="redirect_custom_url"
|
|
209
|
+
label="Custom URL"
|
|
210
|
+
validate={[required()]}
|
|
211
|
+
helperText="Enter the full URL to redirect to"
|
|
212
|
+
fullWidth
|
|
213
|
+
/>
|
|
214
|
+
)}
|
|
215
|
+
</Box>
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return null;
|
|
220
|
+
}}
|
|
221
|
+
</FormDataConsumer>
|
|
222
|
+
|
|
223
|
+
<BooleanInput source="allow_failure" label="Allow Failure" />
|
|
224
|
+
</SimpleFormIterator>
|
|
225
|
+
</ArrayInput>
|
|
226
|
+
|
|
227
|
+
<Box sx={{ mt: 3 }}>
|
|
228
|
+
<Labeled label="Created At">
|
|
229
|
+
<DateField source="created_at" showTime={true} />
|
|
230
|
+
</Labeled>
|
|
231
|
+
<Labeled label="Updated At">
|
|
232
|
+
<DateField source="updated_at" showTime={true} />
|
|
233
|
+
</Labeled>
|
|
234
|
+
</Box>
|
|
235
|
+
</SimpleForm>
|
|
236
|
+
</Edit>
|
|
237
|
+
);
|
|
238
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { List, Datagrid, TextField, DateField } from "react-admin";
|
|
2
|
+
import { PostListActions } from "../listActions/PostListActions";
|
|
3
|
+
|
|
4
|
+
export const FlowsList = () => {
|
|
5
|
+
return (
|
|
6
|
+
<List actions={<PostListActions />}>
|
|
7
|
+
<Datagrid rowClick="edit" bulkActionButtons={false}>
|
|
8
|
+
<TextField source="id" />
|
|
9
|
+
<TextField source="name" />
|
|
10
|
+
<DateField source="created_at" showTime={true} />
|
|
11
|
+
<DateField source="updated_at" showTime={true} />
|
|
12
|
+
</Datagrid>
|
|
13
|
+
</List>
|
|
14
|
+
);
|
|
15
|
+
};
|