authhero 0.0.1 → 1.0.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/.changeset/README.md +8 -0
- package/.changeset/config.json +11 -0
- package/.github/workflows/release.yml +34 -0
- package/.prettierignore +3 -0
- package/.prettierrc.json +1 -0
- package/README.md +9 -4
- package/apps/react-admin/.eslintrc.js +21 -0
- package/apps/react-admin/README.md +50 -0
- package/apps/react-admin/index.html +125 -0
- package/apps/react-admin/package.json +45 -0
- package/apps/react-admin/prettier.config.js +1 -0
- package/apps/react-admin/public/favicon.ico +0 -0
- package/apps/react-admin/public/manifest.json +15 -0
- package/apps/react-admin/src/App.spec.tsx +39 -0
- package/apps/react-admin/src/App.tsx +75 -0
- package/apps/react-admin/src/Layout.tsx +12 -0
- package/apps/react-admin/src/TenantsApp.tsx +21 -0
- package/apps/react-admin/src/auth0DataProvider.ts +220 -0
- package/apps/react-admin/src/authProvider.ts +42 -0
- package/apps/react-admin/src/components/TenantAppBar.tsx +46 -0
- package/apps/react-admin/src/components/TenantLayout.tsx +17 -0
- package/apps/react-admin/src/components/applications/create.tsx +29 -0
- package/apps/react-admin/src/components/applications/edit.tsx +40 -0
- package/apps/react-admin/src/components/applications/index.ts +3 -0
- package/apps/react-admin/src/components/applications/list.tsx +37 -0
- package/apps/react-admin/src/components/common/DateAgo.tsx +6 -0
- package/apps/react-admin/src/components/common/JsonOutput.tsx +3 -0
- package/apps/react-admin/src/components/common/index.ts +1 -0
- package/apps/react-admin/src/components/connections/create.tsx +11 -0
- package/apps/react-admin/src/components/connections/edit.tsx +66 -0
- package/apps/react-admin/src/components/connections/index.ts +3 -0
- package/apps/react-admin/src/components/connections/list.tsx +15 -0
- package/apps/react-admin/src/components/domains/create.tsx +11 -0
- package/apps/react-admin/src/components/domains/edit.tsx +49 -0
- package/apps/react-admin/src/components/domains/index.ts +3 -0
- package/apps/react-admin/src/components/domains/list.tsx +15 -0
- package/apps/react-admin/src/components/listActions/PostListActions.tsx +10 -0
- package/apps/react-admin/src/components/tenants/create.tsx +15 -0
- package/apps/react-admin/src/components/tenants/edit.tsx +51 -0
- package/apps/react-admin/src/components/tenants/index.ts +2 -0
- package/apps/react-admin/src/components/tenants/list.tsx +48 -0
- package/apps/react-admin/src/components/users/create.tsx +15 -0
- package/apps/react-admin/src/components/users/edit.tsx +108 -0
- package/apps/react-admin/src/components/users/index.ts +3 -0
- package/apps/react-admin/src/components/users/list.tsx +30 -0
- package/apps/react-admin/src/data.json +121 -0
- package/apps/react-admin/src/dataProvider.ts +48 -0
- package/apps/react-admin/src/index.tsx +30 -0
- package/apps/react-admin/src/lib/logs.ts +19 -0
- package/apps/react-admin/tsconfig.json +9 -0
- package/apps/react-admin/tsconfig.node.json +4 -0
- package/apps/react-admin/vercel.json +20 -0
- package/apps/react-admin/vite.config.ts +19 -0
- package/eslint.config.mjs +25 -0
- package/package.json +22 -16
- package/packages/authhero/CHANGELOG.md +7 -0
- package/packages/authhero/README.md +9 -0
- package/packages/authhero/package.json +25 -0
- package/packages/authhero/src/bun.ts +16 -0
- package/packages/authhero/src/index.ts +34 -0
- package/packages/authhero/src/routes/oauth2/index.ts +1 -0
- package/packages/authhero/src/routes/oauth2/well-known.ts +179 -0
- package/{src → packages/authhero/src}/types/Bindings.ts +3 -0
- package/packages/authhero/src/types/JWKS.ts +37 -0
- package/packages/authhero/src/types/Variables.ts +1 -0
- package/packages/authhero/src/types/index.ts +3 -0
- package/packages/authhero/src/vite-env.d.ts +1 -0
- package/packages/authhero/tsconfig.json +11 -0
- package/packages/authhero/tsconfig.node.json +4 -0
- package/packages/create-authhero/package.json +22 -0
- package/packages/create-authhero/src/index.ts +72 -0
- package/packages/create-authhero/src/vite-env.d.ts +1 -0
- package/packages/create-authhero/templates/sqlite/package.json +17 -0
- package/packages/create-authhero/templates/sqlite/src/index.ts +19 -0
- package/packages/create-authhero/templates/sqlite/yarn.lock +48 -0
- package/packages/create-authhero/tsconfig.json +9 -0
- package/packages/create-authhero/tsconfig.node.json +4 -0
- package/packages/create-authhero/vite.config.ts +14 -0
- package/pnpm-workspace.yaml +3 -0
- package/tsconfig.json +28 -8
- package/tsconfig.node.json +7 -2
- package/dist/authhero.js +0 -4912
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +0 -1
- package/dist/types/Bindings.d.ts +0 -5
- package/dist/types/Bindings.d.ts.map +0 -1
- package/src/index.ts +0 -13
- /package/{src → apps/react-admin/src}/vite-env.d.ts +0 -0
- /package/{vite.config.ts → packages/authhero/vite.config.ts} +0 -0
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
import querystring from "query-string";
|
|
2
|
+
import { fetchUtils, DataProvider } from "ra-core";
|
|
3
|
+
import { UpdateParams } from "react-admin";
|
|
4
|
+
|
|
5
|
+
function removeExtraFields(params: UpdateParams) {
|
|
6
|
+
// delete params.data?.id; // this is required for patch... but not for put?
|
|
7
|
+
delete params.data?.tenant_id;
|
|
8
|
+
delete params.data?.updated_at;
|
|
9
|
+
delete params.data?.created_at;
|
|
10
|
+
delete params.data?.identities;
|
|
11
|
+
|
|
12
|
+
// hmmmmm, this is an issue we have here with mismatching structure?
|
|
13
|
+
// seems like we need to modify our endpoints to accept connections.
|
|
14
|
+
// TBD with Markus
|
|
15
|
+
delete params.data?.connections;
|
|
16
|
+
|
|
17
|
+
// actually Auth0 does not require this for patching. seems dangerous not to rely on an auto-id
|
|
18
|
+
// as may get rejected for having the same id
|
|
19
|
+
delete params.data?.id;
|
|
20
|
+
// for user we don't want to include this
|
|
21
|
+
delete params.data?.user_id;
|
|
22
|
+
|
|
23
|
+
// extra user fields
|
|
24
|
+
delete params.data?.last_login;
|
|
25
|
+
delete params.data?.provider;
|
|
26
|
+
|
|
27
|
+
// Remove empty properties
|
|
28
|
+
Object.keys(params.data).forEach((key) => {
|
|
29
|
+
if (params.data[key] === undefined) {
|
|
30
|
+
delete params.data[key];
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return params;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getIdKeyFromResource(resource: string) {
|
|
38
|
+
switch (resource) {
|
|
39
|
+
case "connections":
|
|
40
|
+
return "connnection_id";
|
|
41
|
+
case "domains":
|
|
42
|
+
return "domain_id";
|
|
43
|
+
case "users":
|
|
44
|
+
return "user_id";
|
|
45
|
+
case "logs":
|
|
46
|
+
return "log_id";
|
|
47
|
+
case "tenants":
|
|
48
|
+
return "tenant_id";
|
|
49
|
+
case "applications":
|
|
50
|
+
return "application_id";
|
|
51
|
+
default:
|
|
52
|
+
throw new Error(`unknown resource ${resource}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Maps react-admin queries to the auth0 mamagement api
|
|
58
|
+
*/
|
|
59
|
+
export default (
|
|
60
|
+
apiUrl: string,
|
|
61
|
+
httpClient = fetchUtils.fetchJson,
|
|
62
|
+
tenantId?: string,
|
|
63
|
+
): DataProvider => ({
|
|
64
|
+
getList: async (resource, params) => {
|
|
65
|
+
const { page, perPage } = params.pagination || { page: 1, perPage: 10 };
|
|
66
|
+
const { field, order } = params.sort || { field: "id", order: "ASC" };
|
|
67
|
+
|
|
68
|
+
const query = {
|
|
69
|
+
include_totals: true,
|
|
70
|
+
page: page - 1,
|
|
71
|
+
per_page: perPage,
|
|
72
|
+
sort: `${field}:${order === "DESC" ? "-1" : "1"}`,
|
|
73
|
+
q: params.filter.q,
|
|
74
|
+
};
|
|
75
|
+
const url = `${apiUrl}/api/v2/${resource}?${querystring.stringify(query)}`;
|
|
76
|
+
|
|
77
|
+
const headers = new Headers();
|
|
78
|
+
|
|
79
|
+
if (tenantId) {
|
|
80
|
+
headers.set("tenant-id", tenantId);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const res = await httpClient(url, { headers });
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
data: res.json[resource].map((item: any) => ({
|
|
87
|
+
id: item[getIdKeyFromResource(resource)],
|
|
88
|
+
...item,
|
|
89
|
+
})),
|
|
90
|
+
total: res.json.length,
|
|
91
|
+
};
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
getOne: (resource, params) => {
|
|
95
|
+
const headers = new Headers();
|
|
96
|
+
|
|
97
|
+
if (tenantId) {
|
|
98
|
+
headers.set("tenant-id", tenantId);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return httpClient(`${apiUrl}/api/v2/${resource}/${params.id}`, {
|
|
102
|
+
headers,
|
|
103
|
+
}).then(({ json }) => ({
|
|
104
|
+
data: {
|
|
105
|
+
id: json[getIdKeyFromResource(resource)],
|
|
106
|
+
...json,
|
|
107
|
+
},
|
|
108
|
+
}));
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
getMany: (resource, params) => {
|
|
112
|
+
const query = `id:(${params.ids.join(" ")})})`;
|
|
113
|
+
|
|
114
|
+
const url = `${apiUrl}/api/v2/${resource}?q=${query}`;
|
|
115
|
+
return httpClient(url).then(({ json }) => ({
|
|
116
|
+
data: {
|
|
117
|
+
id: json[getIdKeyFromResource(resource)],
|
|
118
|
+
...json,
|
|
119
|
+
},
|
|
120
|
+
}));
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
getManyReference: async (resource, params) => {
|
|
124
|
+
const { page, perPage } = params.pagination;
|
|
125
|
+
const { field, order } = params.sort;
|
|
126
|
+
|
|
127
|
+
if (resource !== "logs") {
|
|
128
|
+
return Promise.reject(
|
|
129
|
+
"not supporting getManyReference for anything but resource logs",
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const query = {
|
|
134
|
+
include_totals: true,
|
|
135
|
+
page: page - 1,
|
|
136
|
+
per_page: perPage,
|
|
137
|
+
sort: `${field}:${order === "DESC" ? "-1" : "1"}`,
|
|
138
|
+
q: `user_id:${params.id}`,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const headers = new Headers();
|
|
142
|
+
|
|
143
|
+
if (tenantId) {
|
|
144
|
+
headers.set("tenant-id", tenantId);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const url = `${apiUrl}/api/v2/${resource}?${querystring.stringify(query)}`;
|
|
148
|
+
|
|
149
|
+
const res = await httpClient(url, { headers });
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
data: res.json.logs.map((item: any) => ({
|
|
153
|
+
id: item[getIdKeyFromResource(resource)],
|
|
154
|
+
...item,
|
|
155
|
+
})),
|
|
156
|
+
total: res.json.length,
|
|
157
|
+
};
|
|
158
|
+
},
|
|
159
|
+
|
|
160
|
+
update: (resource, params) => {
|
|
161
|
+
const headers = new Headers();
|
|
162
|
+
|
|
163
|
+
if (tenantId) {
|
|
164
|
+
headers.set("tenant-id", tenantId);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const cleanParams = removeExtraFields(params);
|
|
168
|
+
|
|
169
|
+
return httpClient(`${apiUrl}/api/v2/${resource}/${params.id}`, {
|
|
170
|
+
headers,
|
|
171
|
+
method: "PATCH",
|
|
172
|
+
body: JSON.stringify(cleanParams.data),
|
|
173
|
+
}).then(({ json }) => ({ data: json }));
|
|
174
|
+
},
|
|
175
|
+
|
|
176
|
+
updateMany: () => Promise.reject("not supporting updateMany"),
|
|
177
|
+
|
|
178
|
+
create: async (resource, params) => {
|
|
179
|
+
const headers = new Headers();
|
|
180
|
+
|
|
181
|
+
if (tenantId) {
|
|
182
|
+
headers.set("tenant-id", tenantId);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const res = await httpClient(`${apiUrl}/api/v2/${resource}`, {
|
|
186
|
+
method: "POST",
|
|
187
|
+
body: JSON.stringify(params.data),
|
|
188
|
+
headers,
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
const data = {
|
|
192
|
+
...res.json,
|
|
193
|
+
id: res.json.id,
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
data,
|
|
198
|
+
};
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
delete: async (resource, params) => {
|
|
202
|
+
const headers = new Headers({
|
|
203
|
+
"Content-Type": "text/plain",
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
if (tenantId) {
|
|
207
|
+
headers.set("tenant-id", tenantId);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const res = await httpClient(`${apiUrl}/api/v2/${resource}/${params.id}`, {
|
|
211
|
+
method: "DELETE",
|
|
212
|
+
headers,
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
data: res.json,
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
deleteMany: () => Promise.reject("not supporting updateMany"),
|
|
220
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Auth0AuthProvider, httpClient } from "ra-auth-auth0";
|
|
2
|
+
import { Auth0Client } from "@auth0/auth0-spa-js";
|
|
3
|
+
|
|
4
|
+
const getUrlByEnvironment = () => {
|
|
5
|
+
// eslint-disable-next-line no-undef
|
|
6
|
+
const VITE_VERCEL_URL = process.env.VITE_VERCEL_URL;
|
|
7
|
+
|
|
8
|
+
if (VITE_VERCEL_URL) {
|
|
9
|
+
return `https://${VITE_VERCEL_URL}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// rename this? and nuke VITE_LOGIN_REDIRECT_URL env var
|
|
13
|
+
return import.meta.env.VITE_LOGOUT_REDIRECT_URL;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const baseRedirectUri = getUrlByEnvironment();
|
|
17
|
+
|
|
18
|
+
const auth0 = new Auth0Client({
|
|
19
|
+
domain: import.meta.env.VITE_AUTH0_DOMAIN,
|
|
20
|
+
clientId: import.meta.env.VITE_AUTH0_CLIENT_ID,
|
|
21
|
+
cacheLocation: "localstorage",
|
|
22
|
+
authorizationParams: {
|
|
23
|
+
audience: import.meta.env.VITE_AUTH0_AUDIENCE,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const authProvider = Auth0AuthProvider(auth0, {
|
|
28
|
+
loginRedirectUri: `${getUrlByEnvironment()}/auth-callback`,
|
|
29
|
+
logoutRedirectUri: getUrlByEnvironment(),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const authorizedHttpClient = httpClient(auth0);
|
|
33
|
+
|
|
34
|
+
// Temp debug code
|
|
35
|
+
// function logAccessToken() {
|
|
36
|
+
// auth0.getTokenSilently().then((token) => {
|
|
37
|
+
// console.log("Access Token: ", token);
|
|
38
|
+
// });
|
|
39
|
+
// }
|
|
40
|
+
// logAccessToken();
|
|
41
|
+
|
|
42
|
+
export { authProvider, authorizedHttpClient };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { AppBar, TitlePortal } from "react-admin";
|
|
2
|
+
import { useEffect, useState } from "react";
|
|
3
|
+
import { Link } from "@mui/material";
|
|
4
|
+
import { authorizedHttpClient } from "../authProvider";
|
|
5
|
+
|
|
6
|
+
type TenantResponse = {
|
|
7
|
+
audience: string;
|
|
8
|
+
created_at: string;
|
|
9
|
+
id: string;
|
|
10
|
+
language: string;
|
|
11
|
+
logo: string;
|
|
12
|
+
updated_at: string;
|
|
13
|
+
name: string;
|
|
14
|
+
primary_color: string;
|
|
15
|
+
secondary_color: string;
|
|
16
|
+
sender_email: string;
|
|
17
|
+
sender_name: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function TenantAppBar() {
|
|
21
|
+
const pathSegments = location.pathname.split("/").filter(Boolean);
|
|
22
|
+
const tenantId = pathSegments[0];
|
|
23
|
+
const [tenant, setTenant] = useState<TenantResponse>();
|
|
24
|
+
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
authorizedHttpClient(
|
|
27
|
+
`${import.meta.env.VITE_SIMPLE_REST_URL}/api/v2/tenants/${tenantId}`,
|
|
28
|
+
{},
|
|
29
|
+
).then((response) => {
|
|
30
|
+
const res: TenantResponse = JSON.parse(response.body);
|
|
31
|
+
setTenant(res);
|
|
32
|
+
});
|
|
33
|
+
}, [tenantId]);
|
|
34
|
+
|
|
35
|
+
const isDefaultSettings = tenantId === "DEFAULT_SETTINGS";
|
|
36
|
+
|
|
37
|
+
return (
|
|
38
|
+
<AppBar sx={{ ...(isDefaultSettings && { backgroundColor: "red" }) }}>
|
|
39
|
+
<TitlePortal />
|
|
40
|
+
<p>{tenant?.name} - </p>
|
|
41
|
+
<Link color="inherit" href="/tenants" underline="none">
|
|
42
|
+
Tenants
|
|
43
|
+
</Link>
|
|
44
|
+
</AppBar>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Layout } from "react-admin";
|
|
2
|
+
|
|
3
|
+
import { TenantAppBar } from "./TenantAppBar";
|
|
4
|
+
|
|
5
|
+
export function tenantLayout(props: any) {
|
|
6
|
+
const tenantId = location.pathname.split("/").filter(Boolean)[0];
|
|
7
|
+
|
|
8
|
+
const isDefaultSettings = tenantId === "DEFAULT_SETTINGS";
|
|
9
|
+
|
|
10
|
+
return (
|
|
11
|
+
<Layout
|
|
12
|
+
{...props}
|
|
13
|
+
appBar={TenantAppBar}
|
|
14
|
+
sx={{ ...(isDefaultSettings && { backgroundColor: "red" }) }}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Create,
|
|
3
|
+
SimpleForm,
|
|
4
|
+
TextInput,
|
|
5
|
+
required,
|
|
6
|
+
SelectInput,
|
|
7
|
+
} from "react-admin";
|
|
8
|
+
|
|
9
|
+
export function ApplicationCreate() {
|
|
10
|
+
return (
|
|
11
|
+
<Create>
|
|
12
|
+
<SimpleForm>
|
|
13
|
+
<TextInput source="name" validate={[required()]} />
|
|
14
|
+
<TextInput source="allowed_callback_urls" fullWidth multiline={true} />
|
|
15
|
+
<TextInput source="allowed_logout_urls" fullWidth multiline={true} />
|
|
16
|
+
<TextInput source="allowed_web_origins" fullWidth multiline={true} />
|
|
17
|
+
<TextInput source="id" validate={[required()]} />
|
|
18
|
+
<SelectInput
|
|
19
|
+
source="email_validation"
|
|
20
|
+
choices={[
|
|
21
|
+
{ id: "disabled", name: "Disabled" },
|
|
22
|
+
{ id: "enabled", name: "Enabled" },
|
|
23
|
+
{ id: "enforced", name: "Enforced" },
|
|
24
|
+
]}
|
|
25
|
+
/>
|
|
26
|
+
</SimpleForm>
|
|
27
|
+
</Create>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DateField,
|
|
3
|
+
Edit,
|
|
4
|
+
FieldTitle,
|
|
5
|
+
Labeled,
|
|
6
|
+
SelectInput,
|
|
7
|
+
SimpleForm,
|
|
8
|
+
TextInput,
|
|
9
|
+
BooleanInput,
|
|
10
|
+
} from "react-admin";
|
|
11
|
+
|
|
12
|
+
export function ApplicationEdit() {
|
|
13
|
+
return (
|
|
14
|
+
<Edit>
|
|
15
|
+
<SimpleForm>
|
|
16
|
+
<TextInput source="id" />
|
|
17
|
+
<TextInput source="name" />
|
|
18
|
+
<TextInput source="client_secret" />
|
|
19
|
+
<SelectInput
|
|
20
|
+
source="email_validation"
|
|
21
|
+
choices={[
|
|
22
|
+
{ id: "disabled", name: "Disabled" },
|
|
23
|
+
{ id: "enabled", name: "Enabled" },
|
|
24
|
+
{ id: "enforced", name: "Enforced" },
|
|
25
|
+
]}
|
|
26
|
+
/>
|
|
27
|
+
<BooleanInput source="disable_sign_ups" />
|
|
28
|
+
<TextInput source="allowed_callback_urls" fullWidth multiline={true} />
|
|
29
|
+
<TextInput source="allowed_logout_urls" fullWidth multiline={true} />
|
|
30
|
+
<TextInput source="allowed_web_origins" fullWidth multiline={true} />
|
|
31
|
+
<Labeled label={<FieldTitle source="created_at" />}>
|
|
32
|
+
<DateField source="created_at" showTime={true} />
|
|
33
|
+
</Labeled>
|
|
34
|
+
<Labeled label={<FieldTitle source="updated_at" />}>
|
|
35
|
+
<DateField source="updated_at" showTime={true} />
|
|
36
|
+
</Labeled>
|
|
37
|
+
</SimpleForm>
|
|
38
|
+
</Edit>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
List,
|
|
3
|
+
Datagrid,
|
|
4
|
+
TextField,
|
|
5
|
+
DateField,
|
|
6
|
+
FunctionField,
|
|
7
|
+
} from "react-admin";
|
|
8
|
+
import { PostListActions } from "../listActions/PostListActions";
|
|
9
|
+
|
|
10
|
+
export function ApplicationsList() {
|
|
11
|
+
return (
|
|
12
|
+
<List actions={<PostListActions />}>
|
|
13
|
+
<Datagrid rowClick="edit" bulkActionButtons={false}>
|
|
14
|
+
<TextField source="id" />
|
|
15
|
+
<TextField source="name" />
|
|
16
|
+
<FunctionField
|
|
17
|
+
label="Login"
|
|
18
|
+
render={(record: any) => (
|
|
19
|
+
<a
|
|
20
|
+
href={`${
|
|
21
|
+
import.meta.env.VITE_SIMPLE_REST_URL
|
|
22
|
+
}/authorize?client_id=${record.id}&redirect_uri=${
|
|
23
|
+
import.meta.env.VITE_SIMPLE_REST_URL
|
|
24
|
+
}/u/info&scope=profile%20email%20openid&state=1234&response_type=code`}
|
|
25
|
+
target="_blank"
|
|
26
|
+
rel="noopener noreferrer"
|
|
27
|
+
>
|
|
28
|
+
Login
|
|
29
|
+
</a>
|
|
30
|
+
)}
|
|
31
|
+
/>
|
|
32
|
+
<DateField source="created_at" showTime={true} />
|
|
33
|
+
<DateField source="updated_at" showTime={true} />
|
|
34
|
+
</Datagrid>
|
|
35
|
+
</List>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./DateAgo";
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DateField,
|
|
3
|
+
Edit,
|
|
4
|
+
FieldTitle,
|
|
5
|
+
Labeled,
|
|
6
|
+
SelectInput,
|
|
7
|
+
SimpleForm,
|
|
8
|
+
TextInput,
|
|
9
|
+
} from "react-admin";
|
|
10
|
+
|
|
11
|
+
export function ConnectionEdit() {
|
|
12
|
+
return (
|
|
13
|
+
<Edit>
|
|
14
|
+
<SimpleForm>
|
|
15
|
+
<TextInput source="id" />
|
|
16
|
+
<TextInput source="name" />
|
|
17
|
+
<TextInput
|
|
18
|
+
source="client_id"
|
|
19
|
+
label="Client ID"
|
|
20
|
+
style={{ width: "800px" }}
|
|
21
|
+
/>
|
|
22
|
+
<TextInput
|
|
23
|
+
source="client_secret"
|
|
24
|
+
label="Client Secret"
|
|
25
|
+
style={{ width: "800px" }}
|
|
26
|
+
/>
|
|
27
|
+
<SelectInput
|
|
28
|
+
source="response_type"
|
|
29
|
+
label="Response Type"
|
|
30
|
+
choices={[
|
|
31
|
+
{ id: "code", name: "Code" },
|
|
32
|
+
{ id: "code id_token", name: "Code ID-token" },
|
|
33
|
+
]}
|
|
34
|
+
/>
|
|
35
|
+
<SelectInput
|
|
36
|
+
source="response_mode"
|
|
37
|
+
label="Response Mode"
|
|
38
|
+
choices={[
|
|
39
|
+
{ id: "query", name: "Query" },
|
|
40
|
+
{ id: "fragment", name: "Fragment" },
|
|
41
|
+
{ id: "web_message", name: "Web Message" },
|
|
42
|
+
{ id: "form_post", name: "Form Post" },
|
|
43
|
+
]}
|
|
44
|
+
/>
|
|
45
|
+
<TextInput source="scope" fullWidth />
|
|
46
|
+
<TextInput
|
|
47
|
+
source="private_key"
|
|
48
|
+
label="Private Key"
|
|
49
|
+
style={{ width: "800px" }}
|
|
50
|
+
multiline={true}
|
|
51
|
+
/>
|
|
52
|
+
<TextInput source="kid" label="Key ID" />
|
|
53
|
+
<TextInput source="team_id" label="Team ID" />
|
|
54
|
+
<TextInput source="token_endpoint" fullWidth />
|
|
55
|
+
<TextInput source="authorization_endpoint" fullWidth />
|
|
56
|
+
<TextInput source="userinfo_endpoint" fullWidth />
|
|
57
|
+
<Labeled label={<FieldTitle source="created_at" />}>
|
|
58
|
+
<DateField source="created_at" showTime={true} />
|
|
59
|
+
</Labeled>
|
|
60
|
+
<Labeled label={<FieldTitle source="updated_at" />}>
|
|
61
|
+
<DateField source="updated_at" showTime={true} />
|
|
62
|
+
</Labeled>
|
|
63
|
+
</SimpleForm>
|
|
64
|
+
</Edit>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { List, Datagrid, TextField, DateField } from "react-admin";
|
|
2
|
+
import { PostListActions } from "../listActions/PostListActions";
|
|
3
|
+
|
|
4
|
+
export function ConnectionsList() {
|
|
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
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DateField,
|
|
3
|
+
Edit,
|
|
4
|
+
FieldTitle,
|
|
5
|
+
Labeled,
|
|
6
|
+
SelectInput,
|
|
7
|
+
SimpleForm,
|
|
8
|
+
TextInput,
|
|
9
|
+
} from "react-admin";
|
|
10
|
+
|
|
11
|
+
export function DomainEdit() {
|
|
12
|
+
return (
|
|
13
|
+
<Edit>
|
|
14
|
+
<SimpleForm>
|
|
15
|
+
<TextInput source="domain" />
|
|
16
|
+
<SelectInput
|
|
17
|
+
source="email_service"
|
|
18
|
+
choices={[
|
|
19
|
+
{ id: "mailchannels", name: "Mailchannels" },
|
|
20
|
+
{ id: "mailgun", name: "Mailgun" },
|
|
21
|
+
]}
|
|
22
|
+
/>
|
|
23
|
+
<TextInput
|
|
24
|
+
label="PEM Private Key"
|
|
25
|
+
source="dkim_private_key"
|
|
26
|
+
style={{ width: "800px" }}
|
|
27
|
+
multiline={true}
|
|
28
|
+
/>
|
|
29
|
+
<TextInput
|
|
30
|
+
label="PEM Public Key"
|
|
31
|
+
source="dkim_public_key"
|
|
32
|
+
style={{ width: "800px" }}
|
|
33
|
+
multiline={true}
|
|
34
|
+
/>
|
|
35
|
+
<TextInput
|
|
36
|
+
label="Api Key"
|
|
37
|
+
source="email_api_key"
|
|
38
|
+
style={{ width: "800px" }}
|
|
39
|
+
/>
|
|
40
|
+
<Labeled label={<FieldTitle source="created_at" />}>
|
|
41
|
+
<DateField source="created_at" showTime={true} />
|
|
42
|
+
</Labeled>
|
|
43
|
+
<Labeled label={<FieldTitle source="updated_at" />}>
|
|
44
|
+
<DateField source="updated_at" showTime={true} />
|
|
45
|
+
</Labeled>
|
|
46
|
+
</SimpleForm>
|
|
47
|
+
</Edit>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { List, Datagrid, TextField, DateField } from "react-admin";
|
|
2
|
+
import { PostListActions } from "../listActions/PostListActions";
|
|
3
|
+
|
|
4
|
+
export function DomainList() {
|
|
5
|
+
return (
|
|
6
|
+
<List actions={<PostListActions />}>
|
|
7
|
+
<Datagrid rowClick="edit" bulkActionButtons={false}>
|
|
8
|
+
<TextField source="id" />
|
|
9
|
+
<TextField source="domain" />
|
|
10
|
+
<DateField source="created_at" showTime={true} />
|
|
11
|
+
<DateField source="updated_at" showTime={true} />
|
|
12
|
+
</Datagrid>
|
|
13
|
+
</List>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Create, SimpleForm, TextInput, required } from "react-admin";
|
|
2
|
+
|
|
3
|
+
export function TenantsCreate() {
|
|
4
|
+
return (
|
|
5
|
+
<Create>
|
|
6
|
+
<SimpleForm>
|
|
7
|
+
<TextInput source="name" validate={[required()]} />
|
|
8
|
+
<TextInput source="audience" validate={[required()]} />
|
|
9
|
+
<TextInput source="sender_email" validate={[required()]} />
|
|
10
|
+
<TextInput source="sender_name" validate={[required()]} />
|
|
11
|
+
<TextInput source="support_url" label="Support Url" />
|
|
12
|
+
</SimpleForm>
|
|
13
|
+
</Create>
|
|
14
|
+
);
|
|
15
|
+
}
|