@ebubekirylmaz/link-test 1.1.12 → 1.2.16
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/package.json +2 -2
- package/src/http/index.js +10 -4
- package/src/layouts/auth/modern.jsx +26 -10
- package/src/layouts/common/ProjectBar/index.jsx +15 -22
- package/src/lib/AddItemWizard/AddItemWizard.jsx +3 -3
- package/src/lib/CustomBreadcrumbs/CustomBreadcrumbs.jsx +1 -1
- package/src/lib/CustomPopover/usePopover.js +1 -1
- package/src/lib/FormProvider/FormProvider.jsx +1 -1
- package/src/lib/ItemSummary/ItemSummary.jsx +1 -0
- package/src/lib/ItemSummary/ItemsSummary.jsx +1 -0
- package/src/lib/RHFTextfield/RHFTextfield.jsx +3 -2
- package/src/lib/SearchNotFound/SearchNotFound.jsx +1 -1
- package/src/lib/SvgColor/SvgColor.jsx +2 -1
- package/src/lib/TableHeadCustom/TableHeadCustom.jsx +1 -1
- package/src/lib/TableSelectedAction/TableSelectedAction.jsx +1 -1
- package/src/lib/useChart/useChart.js +1 -0
- package/src/lib/useTable/useTable.js +1 -1
- package/src/pages/LoginPage.jsx +2 -1
- package/src/widgets/Login/AmplifyLogin.jsx +54 -0
- package/src/widgets/Login/DemoLogin.jsx +142 -21
- package/src/widgets/Login/amplify.jsx +26 -0
- package/src/widgets/Login/amplifyAuth.jsx +25 -0
- package/vite/vite.js +10 -1
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ebubekirylmaz/link-test",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.16",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"private": false,
|
|
6
5
|
"exports": {
|
|
7
6
|
".": "./index.js",
|
|
8
7
|
"./layouts": "./src/layouts/index.js",
|
|
@@ -35,6 +34,7 @@
|
|
|
35
34
|
"@nucleoidai/react-event": "^1.1.9",
|
|
36
35
|
"@nucleoidjs/webstorage": "^1.0.5",
|
|
37
36
|
"autosuggest-highlight": "^3.3.4",
|
|
37
|
+
"aws-amplify": "^6.16.0",
|
|
38
38
|
"axios": "^1.10.0",
|
|
39
39
|
"axios-auth-refresh": "^3.3.6",
|
|
40
40
|
"axios-retry": "^4.4.1",
|
package/src/http/index.js
CHANGED
|
@@ -86,9 +86,7 @@ export const fetcher = (url) => instance.get(url).then((res) => res.data);
|
|
|
86
86
|
const refreshAuthLogic = async (failedRequest) => {
|
|
87
87
|
try {
|
|
88
88
|
const { appId } = config();
|
|
89
|
-
|
|
90
89
|
const projectId = storage.get("projectId");
|
|
91
|
-
|
|
92
90
|
const identityProvider = storage.get("link", "identityProvider");
|
|
93
91
|
|
|
94
92
|
const { data } = await oauth.post("/oauth", {
|
|
@@ -96,17 +94,25 @@ const refreshAuthLogic = async (failedRequest) => {
|
|
|
96
94
|
appId,
|
|
97
95
|
projectId,
|
|
98
96
|
identityProvider,
|
|
97
|
+
...(identityProvider === "DEMO" && {
|
|
98
|
+
username: "admin",
|
|
99
|
+
password: "admin",
|
|
100
|
+
}),
|
|
99
101
|
});
|
|
100
102
|
|
|
101
|
-
const accessToken = data
|
|
103
|
+
const { accessToken, refreshToken } = data;
|
|
102
104
|
|
|
103
105
|
failedRequest.response.config.headers["Authorization"] =
|
|
104
106
|
"Bearer " + accessToken;
|
|
105
107
|
|
|
106
108
|
storage.set("link", "accessToken", accessToken);
|
|
109
|
+
if (refreshToken) {
|
|
110
|
+
storage.set("link", "refreshToken", refreshToken);
|
|
111
|
+
}
|
|
112
|
+
|
|
107
113
|
return Promise.resolve();
|
|
108
114
|
} catch (error) {
|
|
109
|
-
const {
|
|
115
|
+
const { base } = config();
|
|
110
116
|
|
|
111
117
|
storage.remove("link", "accessToken");
|
|
112
118
|
storage.remove("link", "refreshToken");
|
|
@@ -4,6 +4,7 @@ import Logo from "../../components/logo";
|
|
|
4
4
|
import { Outlet } from "react-router";
|
|
5
5
|
import React from "react";
|
|
6
6
|
import Stack from "@mui/material/Stack";
|
|
7
|
+
import { alpha } from "@mui/material/styles";
|
|
7
8
|
import { useResponsive } from "../../hooks/use-responsive";
|
|
8
9
|
|
|
9
10
|
// ----------------------------------------------------------------------
|
|
@@ -16,28 +17,37 @@ export default function AuthModernLayout({ image }) {
|
|
|
16
17
|
sx={{
|
|
17
18
|
width: 1,
|
|
18
19
|
mx: "auto",
|
|
19
|
-
maxWidth:
|
|
20
|
-
px: { xs:
|
|
20
|
+
maxWidth: 600,
|
|
21
|
+
px: { xs: 3, md: 10 },
|
|
22
|
+
py: { xs: 4, md: 0 },
|
|
21
23
|
height: "100vh",
|
|
22
24
|
justifyContent: "center",
|
|
23
25
|
alignItems: "center",
|
|
24
26
|
}}
|
|
25
27
|
>
|
|
26
28
|
<Logo
|
|
27
|
-
maxSize={
|
|
29
|
+
maxSize={140}
|
|
28
30
|
sx={{
|
|
29
|
-
|
|
30
|
-
mb: { xs: 10, md: 8 },
|
|
31
|
+
mb: { xs: 1, md: 2 },
|
|
31
32
|
}}
|
|
32
33
|
/>
|
|
33
34
|
|
|
34
35
|
<Card
|
|
35
36
|
sx={{
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
width: 1,
|
|
38
|
+
py: { xs: 6, md: 8 },
|
|
39
|
+
px: { xs: 4, md: 6 },
|
|
40
|
+
boxShadow: {
|
|
41
|
+
xs: (theme) =>
|
|
42
|
+
`0 0 2px ${alpha(
|
|
43
|
+
theme.palette.grey[500],
|
|
44
|
+
0.16
|
|
45
|
+
)}, 0 12px 24px -4px ${alpha(theme.palette.grey[500], 0.12)}`,
|
|
46
|
+
md: "none",
|
|
47
|
+
},
|
|
39
48
|
overflow: { md: "unset" },
|
|
40
|
-
bgcolor: { md: "
|
|
49
|
+
bgcolor: { md: "transparent" },
|
|
50
|
+
borderRadius: 2,
|
|
41
51
|
}}
|
|
42
52
|
>
|
|
43
53
|
<Outlet />
|
|
@@ -46,7 +56,12 @@ export default function AuthModernLayout({ image }) {
|
|
|
46
56
|
);
|
|
47
57
|
|
|
48
58
|
const renderSection = (
|
|
49
|
-
<Stack
|
|
59
|
+
<Stack
|
|
60
|
+
flexGrow={1}
|
|
61
|
+
sx={{
|
|
62
|
+
position: "relative",
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
50
65
|
<Box
|
|
51
66
|
component="img"
|
|
52
67
|
alt="auth"
|
|
@@ -59,6 +74,7 @@ export default function AuthModernLayout({ image }) {
|
|
|
59
74
|
position: "absolute",
|
|
60
75
|
width: "calc(60% - 32px)",
|
|
61
76
|
height: "calc(60% - 32px)",
|
|
77
|
+
borderRadius: 3,
|
|
62
78
|
}}
|
|
63
79
|
/>
|
|
64
80
|
</Stack>
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import { Button, DialogActions } from "@mui/material";
|
|
2
|
+
import Dialog, { dialogClasses } from "@mui/material/Dialog";
|
|
3
|
+
import React, { useCallback, useState } from "react";
|
|
4
|
+
import { publish, useEvent } from "@nucleoidai/react-event";
|
|
5
|
+
import { storage, useStorage } from "@nucleoidjs/webstorage";
|
|
6
|
+
import { useMediaQuery, useTheme } from "@mui/material";
|
|
7
|
+
|
|
1
8
|
import Box from "@mui/material/Box";
|
|
2
9
|
import IconButton from "@mui/material/IconButton";
|
|
3
10
|
import Iconify from "../../../components/Iconify";
|
|
@@ -22,13 +29,6 @@ import { useEventListener } from "../../../hooks/use-event-listener";
|
|
|
22
29
|
import { useNavigate } from "react-router-dom";
|
|
23
30
|
import useProjects from "../../../hooks/useProjects";
|
|
24
31
|
|
|
25
|
-
import { Button, DialogActions } from "@mui/material";
|
|
26
|
-
import Dialog, { dialogClasses } from "@mui/material/Dialog";
|
|
27
|
-
import React, { useCallback, useState } from "react";
|
|
28
|
-
import { publish, useEvent } from "@nucleoidai/react-event";
|
|
29
|
-
import { storage, useStorage } from "@nucleoidjs/webstorage";
|
|
30
|
-
import { useMediaQuery, useTheme } from "@mui/material";
|
|
31
|
-
|
|
32
32
|
function ProjectBar() {
|
|
33
33
|
const label = config().template?.projectBar?.label;
|
|
34
34
|
const { appId } = config();
|
|
@@ -94,21 +94,14 @@ function ProjectBar() {
|
|
|
94
94
|
const refreshToken = storage.get("link", "refreshToken");
|
|
95
95
|
const identityProvider = storage.get("link", "identityProvider");
|
|
96
96
|
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
})
|
|
106
|
-
: oauth.post("/oauth", {
|
|
107
|
-
appId,
|
|
108
|
-
refreshToken,
|
|
109
|
-
projectId,
|
|
110
|
-
identityProvider,
|
|
111
|
-
});
|
|
97
|
+
const request = oauth.post("/oauth", {
|
|
98
|
+
appId,
|
|
99
|
+
refreshToken,
|
|
100
|
+
projectId,
|
|
101
|
+
identityProvider,
|
|
102
|
+
username: "admin",
|
|
103
|
+
password: "admin",
|
|
104
|
+
});
|
|
112
105
|
|
|
113
106
|
request
|
|
114
107
|
.then(({ data }) => {
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { Grid, Stack, Switch, Typography } from "@mui/material";
|
|
2
|
+
import { publish, useEvent } from "@nucleoidai/react-event";
|
|
3
|
+
|
|
1
4
|
import Dialog from "@mui/material/Dialog";
|
|
2
5
|
import DialogContent from "@mui/material/DialogContent";
|
|
3
6
|
import DialogTitle from "@mui/material/DialogTitle";
|
|
@@ -7,9 +10,6 @@ import SelectAvatar from "../IconSelector/IconSelector";
|
|
|
7
10
|
import SparkleInput from "../SparkleInput/SparkleInput";
|
|
8
11
|
import StepComponent from "../StepComponent/StepComponent";
|
|
9
12
|
|
|
10
|
-
import { Grid, Stack, Switch, Typography } from "@mui/material";
|
|
11
|
-
import { publish, useEvent } from "@nucleoidai/react-event";
|
|
12
|
-
|
|
13
13
|
function AddItemWizard({ onSubmit, items, steps, stepExp }) {
|
|
14
14
|
const [activeStep, setActiveStep] = React.useState(0);
|
|
15
15
|
const [newItems, setNewItems] = React.useState(items);
|
|
@@ -3,9 +3,9 @@ import Breadcrumbs from "@mui/material/Breadcrumbs";
|
|
|
3
3
|
import Link from "@mui/material/Link";
|
|
4
4
|
import LinkItem from "./link-item";
|
|
5
5
|
import PropTypes from "prop-types";
|
|
6
|
+
import React from "react";
|
|
6
7
|
import Stack from "@mui/material/Stack";
|
|
7
8
|
import Typography from "@mui/material/Typography";
|
|
8
|
-
|
|
9
9
|
export default function CustomBreadcrumbs({
|
|
10
10
|
links,
|
|
11
11
|
action,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { Controller, useFormContext } from "react-hook-form";
|
|
2
|
-
|
|
3
1
|
import PropTypes from "prop-types";
|
|
2
|
+
import React from "react";
|
|
4
3
|
import TextField from "@mui/material/TextField";
|
|
5
4
|
|
|
5
|
+
import { Controller, useFormContext } from "react-hook-form";
|
|
6
|
+
|
|
6
7
|
export default function RHFTextField({ name, helperText, type, ...other }) {
|
|
7
8
|
const { control } = useFormContext();
|
|
8
9
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import Box from "@mui/material/Box";
|
|
2
2
|
import Checkbox from "@mui/material/Checkbox";
|
|
3
3
|
import PropTypes from "prop-types";
|
|
4
|
+
import React from "react";
|
|
4
5
|
import TableCell from "@mui/material/TableCell";
|
|
5
6
|
import TableHead from "@mui/material/TableHead";
|
|
6
7
|
import TableRow from "@mui/material/TableRow";
|
|
7
8
|
import TableSortLabel from "@mui/material/TableSortLabel";
|
|
8
|
-
|
|
9
9
|
const visuallyHidden = {
|
|
10
10
|
border: 0,
|
|
11
11
|
margin: -1,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import Checkbox from "@mui/material/Checkbox";
|
|
2
2
|
import PropTypes from "prop-types";
|
|
3
|
+
import React from "react";
|
|
3
4
|
import Stack from "@mui/material/Stack";
|
|
4
5
|
import Typography from "@mui/material/Typography";
|
|
5
|
-
|
|
6
6
|
export default function TableSelectedAction({
|
|
7
7
|
dense,
|
|
8
8
|
action,
|
package/src/pages/LoginPage.jsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import AmplifyLogin from "../widgets/Login/AmplifyLogin";
|
|
1
2
|
import CognitoLogin from "../widgets/Login/CognitoLogin";
|
|
2
3
|
import DemoLogin from "../widgets/Login/DemoLogin";
|
|
3
4
|
import LoginForm from "../widgets/LoginForm/LoginForm";
|
|
@@ -31,7 +32,7 @@ function LoginPage() {
|
|
|
31
32
|
}, [navigate]);
|
|
32
33
|
|
|
33
34
|
if (credentials?.provider === "COGNITO") {
|
|
34
|
-
return <
|
|
35
|
+
return <AmplifyLogin />;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
if (credentials?.provider === "DEMO") {
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Button, Stack, TextField, Typography } from "@mui/material";
|
|
2
|
+
|
|
3
|
+
import { loginWithAmplify } from "./amplify";
|
|
4
|
+
import { storage } from "@nucleoidjs/webstorage";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
|
|
7
|
+
export default function AmplifyLogin() {
|
|
8
|
+
const [username, setUsername] = useState("");
|
|
9
|
+
const [password, setPassword] = useState("");
|
|
10
|
+
|
|
11
|
+
const handleLogin = async () => {
|
|
12
|
+
try {
|
|
13
|
+
const result = await loginWithAmplify(username, password);
|
|
14
|
+
|
|
15
|
+
if (result.challenge) {
|
|
16
|
+
console.log("Challenge required:", result.challenge);
|
|
17
|
+
alert(`Challenge required: ${result.challenge}`);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log("Login successful, tokens:", result);
|
|
22
|
+
|
|
23
|
+
storage.set("link", "accessToken", result.AccessToken);
|
|
24
|
+
storage.set("link", "refreshToken", result.RefreshToken);
|
|
25
|
+
|
|
26
|
+
window.location.href = "/";
|
|
27
|
+
} catch (e) {
|
|
28
|
+
console.error("Login error:", e);
|
|
29
|
+
alert(`Login failed: ${e.message || e}`);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<>
|
|
35
|
+
<Typography variant="h4">Login</Typography>
|
|
36
|
+
<Stack spacing={2}>
|
|
37
|
+
<TextField
|
|
38
|
+
label="Username or Email"
|
|
39
|
+
value={username}
|
|
40
|
+
onChange={(e) => setUsername(e.target.value)}
|
|
41
|
+
/>
|
|
42
|
+
<TextField
|
|
43
|
+
type="password"
|
|
44
|
+
label="Password"
|
|
45
|
+
value={password}
|
|
46
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
47
|
+
/>
|
|
48
|
+
<Button variant="contained" onClick={handleLogin}>
|
|
49
|
+
Login
|
|
50
|
+
</Button>
|
|
51
|
+
</Stack>
|
|
52
|
+
</>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
@@ -1,19 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Box,
|
|
3
|
+
Button,
|
|
4
|
+
IconButton,
|
|
5
|
+
InputAdornment,
|
|
6
|
+
Stack,
|
|
7
|
+
TextField,
|
|
8
|
+
Typography,
|
|
9
|
+
alpha,
|
|
10
|
+
} from "@mui/material";
|
|
11
|
+
import {
|
|
12
|
+
LockOutlined,
|
|
13
|
+
PersonOutline,
|
|
14
|
+
Visibility,
|
|
15
|
+
VisibilityOff,
|
|
16
|
+
} from "@mui/icons-material";
|
|
17
|
+
import React, { useState } from "react";
|
|
18
|
+
|
|
1
19
|
import config from "../../config/config";
|
|
2
20
|
import { storage } from "@nucleoidjs/webstorage";
|
|
3
21
|
import { useNavigate } from "react-router-dom";
|
|
4
22
|
|
|
5
|
-
import { Button, Stack, TextField, Typography } from "@mui/material";
|
|
6
|
-
import React, { useState } from "react";
|
|
7
|
-
|
|
8
23
|
export default function DemoLogin() {
|
|
9
24
|
const [username, setUsername] = useState("");
|
|
10
25
|
const [password, setPassword] = useState("");
|
|
26
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
11
27
|
const navigate = useNavigate();
|
|
12
28
|
|
|
13
29
|
const { appId } = config();
|
|
14
30
|
|
|
15
31
|
async function handleLogin() {
|
|
16
|
-
const res = await fetch("/api/oauth
|
|
32
|
+
const res = await fetch("/api/oauth", {
|
|
17
33
|
method: "POST",
|
|
18
34
|
headers: { "Content-Type": "application/json" },
|
|
19
35
|
body: JSON.stringify({
|
|
@@ -21,6 +37,7 @@ export default function DemoLogin() {
|
|
|
21
37
|
projectId: "cb16e069-6214-47f1-9922-1f7fe7629525",
|
|
22
38
|
username,
|
|
23
39
|
password,
|
|
40
|
+
identityProvider: "DEMO",
|
|
24
41
|
}),
|
|
25
42
|
});
|
|
26
43
|
|
|
@@ -30,29 +47,133 @@ export default function DemoLogin() {
|
|
|
30
47
|
|
|
31
48
|
storage.set("link", "accessToken", data.accessToken);
|
|
32
49
|
storage.set("link", "refreshToken", data.refreshToken);
|
|
33
|
-
storage.set("link", "identityProvider", "
|
|
50
|
+
storage.set("link", "identityProvider", "DEMO");
|
|
34
51
|
|
|
35
52
|
navigate("/");
|
|
36
53
|
}
|
|
37
54
|
|
|
38
55
|
return (
|
|
39
|
-
<Stack spacing={2}
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
<Stack spacing={2.5}>
|
|
57
|
+
<Stack spacing={2}>
|
|
58
|
+
<TextField
|
|
59
|
+
label="Username"
|
|
60
|
+
value={username}
|
|
61
|
+
onChange={(e) => setUsername(e.target.value)}
|
|
62
|
+
fullWidth
|
|
63
|
+
InputProps={{
|
|
64
|
+
startAdornment: (
|
|
65
|
+
<InputAdornment position="start">
|
|
66
|
+
<PersonOutline sx={{ color: "text.secondary", fontSize: 22 }} />
|
|
67
|
+
</InputAdornment>
|
|
68
|
+
),
|
|
69
|
+
}}
|
|
70
|
+
sx={{
|
|
71
|
+
"& .MuiOutlinedInput-root": {
|
|
72
|
+
fontSize: "1rem",
|
|
73
|
+
"& input": {
|
|
74
|
+
py: 1.5,
|
|
75
|
+
},
|
|
76
|
+
"&:hover fieldset": {
|
|
77
|
+
borderColor: "primary.main",
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
}}
|
|
81
|
+
/>
|
|
82
|
+
|
|
83
|
+
<TextField
|
|
84
|
+
label="Password"
|
|
85
|
+
type={showPassword ? "text" : "password"}
|
|
86
|
+
value={password}
|
|
87
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
88
|
+
fullWidth
|
|
89
|
+
InputProps={{
|
|
90
|
+
startAdornment: (
|
|
91
|
+
<InputAdornment position="start">
|
|
92
|
+
<LockOutlined sx={{ color: "text.secondary", fontSize: 22 }} />
|
|
93
|
+
</InputAdornment>
|
|
94
|
+
),
|
|
95
|
+
endAdornment: (
|
|
96
|
+
<InputAdornment position="end">
|
|
97
|
+
<IconButton
|
|
98
|
+
onClick={() => setShowPassword(!showPassword)}
|
|
99
|
+
edge="end"
|
|
100
|
+
size="small"
|
|
101
|
+
tabIndex={-1}
|
|
102
|
+
>
|
|
103
|
+
{showPassword ? <VisibilityOff /> : <Visibility />}
|
|
104
|
+
</IconButton>
|
|
105
|
+
</InputAdornment>
|
|
106
|
+
),
|
|
107
|
+
}}
|
|
108
|
+
sx={{
|
|
109
|
+
"& .MuiOutlinedInput-root": {
|
|
110
|
+
fontSize: "1rem",
|
|
111
|
+
"& input": {
|
|
112
|
+
py: 1.5,
|
|
113
|
+
},
|
|
114
|
+
"&:hover fieldset": {
|
|
115
|
+
borderColor: "primary.main",
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
}}
|
|
119
|
+
onKeyPress={(e) => {
|
|
120
|
+
if (e.key === "Enter") {
|
|
121
|
+
handleLogin();
|
|
122
|
+
}
|
|
123
|
+
}}
|
|
124
|
+
/>
|
|
125
|
+
</Stack>
|
|
126
|
+
|
|
127
|
+
<Button
|
|
128
|
+
variant="contained"
|
|
129
|
+
onClick={handleLogin}
|
|
130
|
+
size="large"
|
|
131
|
+
fullWidth
|
|
132
|
+
sx={{
|
|
133
|
+
mt: 1,
|
|
134
|
+
py: 1.5,
|
|
135
|
+
fontSize: "1rem",
|
|
136
|
+
fontWeight: 600,
|
|
137
|
+
textTransform: "none",
|
|
138
|
+
borderRadius: 1.5,
|
|
139
|
+
boxShadow: (theme) =>
|
|
140
|
+
`0 8px 16px ${alpha(theme.palette.primary.main, 0.24)}`,
|
|
141
|
+
transition: "all 0.2s cubic-bezier(0.4, 0, 0.2, 1)",
|
|
142
|
+
"&:hover": {
|
|
143
|
+
transform: "translateY(-2px)",
|
|
144
|
+
boxShadow: (theme) =>
|
|
145
|
+
`0 12px 24px ${alpha(theme.palette.primary.main, 0.32)}`,
|
|
146
|
+
},
|
|
147
|
+
"&:active": {
|
|
148
|
+
transform: "translateY(0px)",
|
|
149
|
+
},
|
|
150
|
+
}}
|
|
151
|
+
>
|
|
152
|
+
Sign in
|
|
54
153
|
</Button>
|
|
55
|
-
|
|
154
|
+
|
|
155
|
+
<Box
|
|
156
|
+
sx={{
|
|
157
|
+
mt: 1,
|
|
158
|
+
textAlign: "center",
|
|
159
|
+
p: 2,
|
|
160
|
+
borderRadius: 1.5,
|
|
161
|
+
bgcolor: (theme) => alpha(theme.palette.info.main, 0.08),
|
|
162
|
+
border: (theme) =>
|
|
163
|
+
`1px dashed ${alpha(theme.palette.info.main, 0.24)}`,
|
|
164
|
+
}}
|
|
165
|
+
>
|
|
166
|
+
<Typography
|
|
167
|
+
variant="caption"
|
|
168
|
+
color="text.secondary"
|
|
169
|
+
sx={{ fontSize: "0.8125rem" }}
|
|
170
|
+
>
|
|
171
|
+
Demo credentials:{" "}
|
|
172
|
+
<Box component="strong" sx={{ color: "text.primary" }}>
|
|
173
|
+
admin / admin
|
|
174
|
+
</Box>
|
|
175
|
+
</Typography>
|
|
176
|
+
</Box>
|
|
56
177
|
</Stack>
|
|
57
178
|
);
|
|
58
179
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Auth } from "aws-amplify";
|
|
2
|
+
import { initAmplifyAuth } from "./amplifyAuth";
|
|
3
|
+
|
|
4
|
+
export async function loginWithAmplify(username, password) {
|
|
5
|
+
console.log(Auth.configure());
|
|
6
|
+
|
|
7
|
+
initAmplifyAuth();
|
|
8
|
+
|
|
9
|
+
const user = await Auth.signIn(username, password);
|
|
10
|
+
|
|
11
|
+
// Handle challenges if needed
|
|
12
|
+
if (user.challengeName) {
|
|
13
|
+
return {
|
|
14
|
+
challenge: user.challengeName,
|
|
15
|
+
user,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const session = user.signInUserSession;
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
AccessToken: session.accessToken.jwtToken,
|
|
23
|
+
IdToken: session.idToken.jwtToken,
|
|
24
|
+
RefreshToken: session.refreshToken.token,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Amplify } from "aws-amplify";
|
|
2
|
+
import config from "../../config/config";
|
|
3
|
+
|
|
4
|
+
let initialized = false;
|
|
5
|
+
|
|
6
|
+
export function initAmplifyAuth() {
|
|
7
|
+
if (initialized) return;
|
|
8
|
+
|
|
9
|
+
const { credentials } = config();
|
|
10
|
+
if (!credentials) {
|
|
11
|
+
throw new Error("Cognito credentials not initialized yet");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
Amplify.configure({
|
|
15
|
+
Auth: {
|
|
16
|
+
region: credentials.region,
|
|
17
|
+
userPoolId: credentials.userPoolId,
|
|
18
|
+
userPoolWebClientId: credentials.clientId,
|
|
19
|
+
authenticationFlowType: "USER_SRP_AUTH",
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
initialized = true;
|
|
24
|
+
console.log("Amplify Auth initialized (SRP)");
|
|
25
|
+
}
|
package/vite/vite.js
CHANGED
|
@@ -57,9 +57,18 @@ async function vite() {
|
|
|
57
57
|
rollupOptions: {
|
|
58
58
|
output: {
|
|
59
59
|
entryFileNames: `assets/[name].[hash].js`,
|
|
60
|
-
chunkFileNames:
|
|
60
|
+
chunkFileNames: (chunkInfo) => {
|
|
61
|
+
if (chunkInfo.name === "config") {
|
|
62
|
+
return "config.js";
|
|
63
|
+
}
|
|
64
|
+
return `assets/[name].[hash].js`;
|
|
65
|
+
},
|
|
61
66
|
assetFileNames: `assets/[name].[hash].[ext]`,
|
|
62
67
|
manualChunks(id) {
|
|
68
|
+
if (id.includes("config.js") && !id.includes("node_modules")) {
|
|
69
|
+
return "config";
|
|
70
|
+
}
|
|
71
|
+
|
|
63
72
|
if (id.includes("node_modules")) {
|
|
64
73
|
return id
|
|
65
74
|
.toString()
|