feat: login config
This commit is contained in:
@@ -1,27 +1,28 @@
|
||||
import { fetchBaseQuery } from "@reduxjs/toolkit/query";
|
||||
import toast from "react-hot-toast";
|
||||
import dayjs from "dayjs";
|
||||
import { updateToken, resetAuthData } from "../slices/auth.data";
|
||||
import BASE_URL, { tokenHeader } from "../config";
|
||||
import { fetchBaseQuery } from '@reduxjs/toolkit/query';
|
||||
import toast from 'react-hot-toast';
|
||||
import dayjs from 'dayjs';
|
||||
import { updateToken, resetAuthData } from '../slices/auth.data';
|
||||
import BASE_URL, { tokenHeader } from '../config';
|
||||
const whiteList = [
|
||||
"login",
|
||||
"register",
|
||||
"checkInviteTokenValid",
|
||||
"getServer",
|
||||
"getOpenid",
|
||||
"getMetamaskNonce",
|
||||
"renew",
|
||||
'login',
|
||||
'register',
|
||||
'checkInviteTokenValid',
|
||||
'getLoginConfig',
|
||||
'getServer',
|
||||
'getOpenid',
|
||||
'getMetamaskNonce',
|
||||
'renew'
|
||||
];
|
||||
const baseQuery = fetchBaseQuery({
|
||||
baseUrl: BASE_URL,
|
||||
prepareHeaders: (headers, { getState, endpoint }) => {
|
||||
console.log("req", endpoint);
|
||||
console.log('req', endpoint);
|
||||
const { token } = getState().authData;
|
||||
if (token && !whiteList.includes(endpoint)) {
|
||||
headers.set(tokenHeader, token);
|
||||
}
|
||||
return headers;
|
||||
},
|
||||
}
|
||||
});
|
||||
let waitingForRenew = null;
|
||||
const baseQueryWithTokenCheck = async (args, api, extraOptions) => {
|
||||
@@ -29,25 +30,18 @@ const baseQueryWithTokenCheck = async (args, api, extraOptions) => {
|
||||
await waitingForRenew;
|
||||
}
|
||||
// 先检查token是否过期,过期则renew
|
||||
const {
|
||||
token,
|
||||
refreshToken,
|
||||
expireTime = new Date().getTime(),
|
||||
} = api.getState().authData;
|
||||
const { token, refreshToken, expireTime = new Date().getTime() } = api.getState().authData;
|
||||
let result = null;
|
||||
if (
|
||||
!whiteList.includes(api.endpoint) &&
|
||||
dayjs().isAfter(new Date(expireTime - 20 * 1000))
|
||||
) {
|
||||
if (!whiteList.includes(api.endpoint) && dayjs().isAfter(new Date(expireTime - 20 * 1000))) {
|
||||
// 快过期了,renew
|
||||
waitingForRenew = baseQuery(
|
||||
{
|
||||
url: "/token/renew",
|
||||
method: "POST",
|
||||
url: '/token/renew',
|
||||
method: 'POST',
|
||||
body: {
|
||||
token,
|
||||
refresh_token: refreshToken,
|
||||
},
|
||||
refresh_token: refreshToken
|
||||
}
|
||||
},
|
||||
api,
|
||||
extraOptions
|
||||
@@ -64,21 +58,21 @@ const baseQueryWithTokenCheck = async (args, api, extraOptions) => {
|
||||
result = await baseQuery(args, api, extraOptions);
|
||||
}
|
||||
if (result?.error) {
|
||||
console.log("api error", result.error, api.endpoint);
|
||||
console.log('api error', result.error, api.endpoint);
|
||||
switch (result.error.originalStatus || result.error.status) {
|
||||
case "FETCH_ERROR":
|
||||
case 'FETCH_ERROR':
|
||||
{
|
||||
toast.error(`${api.endpoint}: Failed to fetch`);
|
||||
}
|
||||
break;
|
||||
case 404:
|
||||
{
|
||||
toast.error("Request Not Found");
|
||||
toast.error('Request Not Found');
|
||||
}
|
||||
break;
|
||||
case 500:
|
||||
{
|
||||
toast.error(result.error.data || "server error");
|
||||
toast.error(result.error.data || 'server error');
|
||||
}
|
||||
break;
|
||||
case 401:
|
||||
@@ -86,15 +80,15 @@ const baseQueryWithTokenCheck = async (args, api, extraOptions) => {
|
||||
// if (api.endpoint === "renew") {
|
||||
// toast.error("token expired, please login again");
|
||||
api.dispatch(resetAuthData());
|
||||
location.href = "/#/login";
|
||||
location.href = '/#/login';
|
||||
// } else {
|
||||
toast.error("API Not Authenticated");
|
||||
toast.error('API Not Authenticated');
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
break;
|
||||
case 403:
|
||||
toast.error("Request Not Allowed");
|
||||
toast.error('Request Not Allowed');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
+53
-44
@@ -1,10 +1,10 @@
|
||||
import { createApi } from "@reduxjs/toolkit/query/react";
|
||||
import BASE_URL from "../config";
|
||||
import { updateInviteLink, updateInfo } from "../slices/server";
|
||||
import baseQuery from "./base.query";
|
||||
import { createApi } from '@reduxjs/toolkit/query/react';
|
||||
import BASE_URL from '../config';
|
||||
import { updateInviteLink, updateInfo } from '../slices/server';
|
||||
import baseQuery from './base.query';
|
||||
const defaultExpireDuration = 7 * 24 * 60 * 60;
|
||||
export const serverApi = createApi({
|
||||
reducerPath: "serverApi",
|
||||
reducerPath: 'serverApi',
|
||||
baseQuery,
|
||||
endpoints: (builder) => ({
|
||||
getServer: builder.query({
|
||||
@@ -18,104 +18,111 @@ export const serverApi = createApi({
|
||||
const { data: server } = await queryFulfilled;
|
||||
dispatch(updateInfo(server));
|
||||
} catch {
|
||||
console.log("get server info error");
|
||||
console.log('get server info error');
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
getMetrics: builder.query({
|
||||
query: () => ({ url: `/admin/system/metrics` }),
|
||||
query: () => ({ url: `/admin/system/metrics` })
|
||||
}),
|
||||
getFirebaseConfig: builder.query({
|
||||
query: () => ({ url: `admin/fcm/config` }),
|
||||
query: () => ({ url: `admin/fcm/config` })
|
||||
}),
|
||||
sendTestEmail: builder.mutation({
|
||||
query: (data) => ({
|
||||
url: `/admin/system/send_mail`,
|
||||
method: "POST",
|
||||
body: data,
|
||||
}),
|
||||
method: 'POST',
|
||||
body: data
|
||||
})
|
||||
}),
|
||||
updateFirebaseConfig: builder.mutation({
|
||||
query: (data) => ({
|
||||
url: `admin/fcm/config`,
|
||||
method: "POST",
|
||||
body: data,
|
||||
}),
|
||||
method: 'POST',
|
||||
body: data
|
||||
})
|
||||
}),
|
||||
getAgoraConfig: builder.query({
|
||||
query: () => ({ url: `admin/agora/config` }),
|
||||
query: () => ({ url: `admin/agora/config` })
|
||||
}),
|
||||
updateAgoraConfig: builder.mutation({
|
||||
query: (data) => ({
|
||||
url: `admin/agora/config`,
|
||||
method: "POST",
|
||||
body: data,
|
||||
}),
|
||||
method: 'POST',
|
||||
body: data
|
||||
})
|
||||
}),
|
||||
getSMTPConfig: builder.query({
|
||||
query: () => ({ url: `admin/smtp/config` }),
|
||||
query: () => ({ url: `admin/smtp/config` })
|
||||
}),
|
||||
updateSMTPConfig: builder.mutation({
|
||||
query: (data) => ({
|
||||
url: `admin/smtp/config`,
|
||||
method: "POST",
|
||||
body: data,
|
||||
method: 'POST',
|
||||
body: data
|
||||
})
|
||||
}),
|
||||
getLoginConfig: builder.query({
|
||||
query: () => ({ url: `admin/login/config` })
|
||||
}),
|
||||
updateLoginConfig: builder.mutation({
|
||||
query: (data) => ({
|
||||
url: `admin/login/config`,
|
||||
method: 'POST',
|
||||
body: data
|
||||
})
|
||||
}),
|
||||
updateLogo: builder.mutation({
|
||||
query: (data) => ({
|
||||
headers: {
|
||||
"content-type": "image/png",
|
||||
'content-type': 'image/png'
|
||||
},
|
||||
url: `admin/system/organization/logo`,
|
||||
method: "POST",
|
||||
body: data,
|
||||
method: 'POST',
|
||||
body: data
|
||||
}),
|
||||
async onQueryStarted(data, { dispatch, queryFulfilled }) {
|
||||
try {
|
||||
await queryFulfilled;
|
||||
dispatch(
|
||||
updateInfo({
|
||||
logo: `${BASE_URL}/resource/organization/logo?t=${new Date().getTime()}`,
|
||||
logo: `${BASE_URL}/resource/organization/logo?t=${new Date().getTime()}`
|
||||
})
|
||||
);
|
||||
} catch {
|
||||
console.log("update server logo error");
|
||||
console.log('update server logo error');
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
createInviteLink: builder.query({
|
||||
query: (expired_in = defaultExpireDuration) => ({
|
||||
headers: {
|
||||
"content-type": "text/plain",
|
||||
accept: "text/plain",
|
||||
'content-type': 'text/plain',
|
||||
accept: 'text/plain'
|
||||
},
|
||||
url: `/admin/user/create_invite_link?expired_in=${expired_in}`,
|
||||
responseHandler: (response) => response.text(),
|
||||
responseHandler: (response) => response.text()
|
||||
}),
|
||||
transformResponse: (link) => {
|
||||
// 替换掉域名
|
||||
const invite = new URL(link);
|
||||
return `${location.origin}${invite.pathname}${invite.search}${invite.hash}`;
|
||||
},
|
||||
async onQueryStarted(
|
||||
expire = defaultExpireDuration,
|
||||
{ dispatch, queryFulfilled }
|
||||
) {
|
||||
async onQueryStarted(expire = defaultExpireDuration, { dispatch, queryFulfilled }) {
|
||||
try {
|
||||
const { data: link } = await queryFulfilled;
|
||||
console.log("link", link);
|
||||
console.log('link', link);
|
||||
dispatch(updateInviteLink({ expire, link }));
|
||||
} catch {
|
||||
console.log("invite link error");
|
||||
console.log('invite link error');
|
||||
}
|
||||
}
|
||||
},
|
||||
}),
|
||||
updateServer: builder.mutation({
|
||||
query: (data) => ({
|
||||
url: `admin/system/organization`,
|
||||
method: "POST",
|
||||
body: data,
|
||||
method: 'POST',
|
||||
body: data
|
||||
}),
|
||||
async onQueryStarted(data, { dispatch, queryFulfilled, getState }) {
|
||||
const { name: prevName, description: prevDesc } = getState().server;
|
||||
@@ -125,15 +132,17 @@ export const serverApi = createApi({
|
||||
} catch {
|
||||
dispatch(updateInfo({ name: prevName, description: prevDesc }));
|
||||
}
|
||||
},
|
||||
}),
|
||||
}),
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
export const {
|
||||
useSendTestEmailMutation,
|
||||
useUpdateFirebaseConfigMutation,
|
||||
useGetFirebaseConfigQuery,
|
||||
useGetLoginConfigQuery,
|
||||
useUpdateLoginConfigMutation,
|
||||
useGetSMTPConfigQuery,
|
||||
useUpdateSMTPConfigMutation,
|
||||
useGetAgoraConfigQuery,
|
||||
@@ -143,5 +152,5 @@ export const {
|
||||
useLazyGetServerQuery,
|
||||
useUpdateServerMutation,
|
||||
useUpdateLogoMutation,
|
||||
useLazyCreateInviteLinkQuery,
|
||||
useLazyCreateInviteLinkQuery
|
||||
} = serverApi;
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
// import { useState, useEffect } from "react";
|
||||
import StyledContainer from './StyledContainer';
|
||||
// import Input from "../../styled/Input";
|
||||
import Textarea from '../../styled/Textarea';
|
||||
import Toggle from '../../styled/Toggle';
|
||||
import Label from '../../styled/Label';
|
||||
import SaveTip from '../../SaveTip';
|
||||
import useConfig from './useConfig';
|
||||
|
||||
export default function Logins() {
|
||||
const { values, updateConfig, setValues, reset, changed } = useConfig('login');
|
||||
const handleUpdate = () => {
|
||||
// const { token_url, description } = values;
|
||||
updateConfig(values);
|
||||
};
|
||||
const handleChange = (evt) => {
|
||||
const newValue = evt.target.value;
|
||||
const { type } = evt.target.dataset;
|
||||
const items = newValue ? newValue.split('\n') : [];
|
||||
setValues((prev) => {
|
||||
return { ...prev, [type]: items };
|
||||
});
|
||||
};
|
||||
const handleToggle = (val) => {
|
||||
setValues((prev) => {
|
||||
return { ...prev, ...val };
|
||||
});
|
||||
};
|
||||
if (!values) return null;
|
||||
const { google, metamask, password, oidc = [] } = values ?? {};
|
||||
return (
|
||||
<StyledContainer>
|
||||
<div className="inputs">
|
||||
<div className="input row">
|
||||
<Label>Password</Label>
|
||||
<Toggle
|
||||
onClick={handleToggle.bind(null, { password: !password })}
|
||||
data-checked={password}
|
||||
></Toggle>
|
||||
</div>
|
||||
<div className="input row">
|
||||
<Label>Google</Label>
|
||||
<Toggle onClick={handleToggle.bind(null, { google: !google })} data-checked={google}></Toggle>
|
||||
</div>
|
||||
<div className="input row">
|
||||
<Label>Metamask</Label>
|
||||
<Toggle
|
||||
onClick={handleToggle.bind(null, { metamask: !metamask })}
|
||||
data-checked={metamask}
|
||||
></Toggle>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">OIDC</Label>
|
||||
<Textarea
|
||||
rows={10}
|
||||
data-type="oidc"
|
||||
onChange={handleChange}
|
||||
value={oidc.join('\n')}
|
||||
name="oidc"
|
||||
placeholder="Input issuer list, one line, one issuer"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* <div className="input">
|
||||
<Label htmlFor="name">Token Url</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="token_url"
|
||||
onChange={handleChange}
|
||||
value={token_url || "https://oauth2.googleapis.com/token"}
|
||||
name="token_url"
|
||||
placeholder="Token URL"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Project ID</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
type={"number"}
|
||||
data-type="project_id"
|
||||
onChange={handleChange}
|
||||
value={project_id}
|
||||
name="project_id"
|
||||
placeholder="Project ID"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Private Key</Label>
|
||||
<Textarea
|
||||
rows={10}
|
||||
disabled={!enabled}
|
||||
data-type="private_key"
|
||||
onChange={handleChange}
|
||||
value={private_key}
|
||||
name="private_key"
|
||||
placeholder="Private key"
|
||||
/>
|
||||
</div>
|
||||
<div className="input">
|
||||
<Label htmlFor="desc">Client Email</Label>
|
||||
<Input
|
||||
disabled={!enabled}
|
||||
data-type="client_email"
|
||||
onChange={handleChange}
|
||||
value={client_email}
|
||||
name="client_email"
|
||||
placeholder="Client Email address"
|
||||
/>
|
||||
</div> */}
|
||||
</div>
|
||||
{changed && <SaveTip saveHandler={handleUpdate} resetHandler={reset} />}
|
||||
{/* <button onClick={handleUpdate} className="btn">update</button> */}
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
@@ -1,55 +1,51 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { isObjectEqual } from "../../../utils";
|
||||
import toast from "react-hot-toast";
|
||||
import { useEffect, useState } from 'react';
|
||||
import { isObjectEqual } from '../../../utils';
|
||||
import toast from 'react-hot-toast';
|
||||
import {
|
||||
useGetAgoraConfigQuery,
|
||||
useGetFirebaseConfigQuery,
|
||||
useGetSMTPConfigQuery,
|
||||
useGetLoginConfigQuery,
|
||||
useUpdateLoginConfigMutation,
|
||||
useUpdateSMTPConfigMutation,
|
||||
useUpdateAgoraConfigMutation,
|
||||
useUpdateFirebaseConfigMutation,
|
||||
} from "../../../../app/services/server";
|
||||
export default function useConfig(config = "smtp") {
|
||||
useUpdateFirebaseConfigMutation
|
||||
} from '../../../../app/services/server';
|
||||
export default function useConfig(config = 'smtp') {
|
||||
const [changed, setChanged] = useState(false);
|
||||
const [values, setValues] = useState({});
|
||||
const { data: Login, refetch: refetchLogin } = useGetLoginConfigQuery();
|
||||
const [updateLoginConfig, { isSuccess: LoginUpdated }] = useUpdateLoginConfigMutation();
|
||||
const { data: SMTP, refetch: refetchSMTP } = useGetSMTPConfigQuery();
|
||||
const [
|
||||
updateSMTPConfig,
|
||||
{ isSuccess: SMTPUpdated },
|
||||
] = useUpdateSMTPConfigMutation();
|
||||
const [updateSMTPConfig, { isSuccess: SMTPUpdated }] = useUpdateSMTPConfigMutation();
|
||||
const { data: Agora, refetch: refetchAgora } = useGetAgoraConfigQuery();
|
||||
const [
|
||||
updateAgoraConfig,
|
||||
{ isSuccess: AgoraUpdated },
|
||||
] = useUpdateAgoraConfigMutation();
|
||||
const {
|
||||
data: Firebase,
|
||||
refetch: refetchFirebase,
|
||||
} = useGetFirebaseConfigQuery();
|
||||
const [
|
||||
updateFirebaseConfig,
|
||||
{ isSuccess: FirebaseUpdated },
|
||||
] = useUpdateFirebaseConfigMutation();
|
||||
const [updateAgoraConfig, { isSuccess: AgoraUpdated }] = useUpdateAgoraConfigMutation();
|
||||
const { data: Firebase, refetch: refetchFirebase } = useGetFirebaseConfigQuery();
|
||||
const [updateFirebaseConfig, { isSuccess: FirebaseUpdated }] = useUpdateFirebaseConfigMutation();
|
||||
|
||||
const datas = {
|
||||
login: Login,
|
||||
smtp: SMTP,
|
||||
agora: Agora,
|
||||
firebase: Firebase,
|
||||
firebase: Firebase
|
||||
};
|
||||
const updateFns = {
|
||||
login: updateLoginConfig,
|
||||
smtp: updateSMTPConfig,
|
||||
agora: updateAgoraConfig,
|
||||
firebase: updateFirebaseConfig,
|
||||
firebase: updateFirebaseConfig
|
||||
};
|
||||
const refetchs = {
|
||||
smtp: refetchSMTP,
|
||||
agora: refetchAgora,
|
||||
firebase: refetchFirebase,
|
||||
login: refetchLogin
|
||||
};
|
||||
const updateds = {
|
||||
login: LoginUpdated,
|
||||
smtp: SMTPUpdated,
|
||||
agora: AgoraUpdated,
|
||||
firebase: FirebaseUpdated,
|
||||
firebase: FirebaseUpdated
|
||||
};
|
||||
const data = datas[config];
|
||||
const updateConfig = updateFns[config];
|
||||
@@ -66,12 +62,12 @@ export default function useConfig(config = "smtp") {
|
||||
};
|
||||
useEffect(() => {
|
||||
if (updated) {
|
||||
toast.success("Configuration Updated!");
|
||||
toast.success('Configuration Updated!');
|
||||
refetch();
|
||||
}
|
||||
}, [updated]);
|
||||
useEffect(() => {
|
||||
console.log("wtf", data);
|
||||
console.log('wtf', data);
|
||||
// if (data) {
|
||||
setValues(data ?? {});
|
||||
// }
|
||||
@@ -91,6 +87,6 @@ export default function useConfig(config = "smtp") {
|
||||
updateConfig,
|
||||
values,
|
||||
setValues,
|
||||
toggleEnable,
|
||||
toggleEnable
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,85 +1,91 @@
|
||||
import { useSelector } from "react-redux";
|
||||
import MyAccount from "./MyAccount";
|
||||
import Overview from "./Overview";
|
||||
import ConfigFirebase from "./config/Firebase";
|
||||
import ConfigSMTP from "./config/SMTP";
|
||||
import Notifications from "./Notifications";
|
||||
import ManageMembers from "../ManageMembers";
|
||||
import FAQ from "../FAQ";
|
||||
import ConfigAgora from "./config/Agora";
|
||||
import { useSelector } from 'react-redux';
|
||||
import MyAccount from './MyAccount';
|
||||
import Overview from './Overview';
|
||||
import Logins from './config/Logins';
|
||||
import ConfigFirebase from './config/Firebase';
|
||||
import ConfigSMTP from './config/SMTP';
|
||||
import Notifications from './Notifications';
|
||||
import ManageMembers from '../ManageMembers';
|
||||
import FAQ from '../FAQ';
|
||||
import ConfigAgora from './config/Agora';
|
||||
const navs = [
|
||||
{
|
||||
title: "General",
|
||||
title: 'General',
|
||||
items: [
|
||||
{
|
||||
name: "overview",
|
||||
title: "Overview",
|
||||
component: <Overview />,
|
||||
name: 'overview',
|
||||
title: 'Overview',
|
||||
component: <Overview />
|
||||
},
|
||||
{
|
||||
name: "members",
|
||||
title: "Members",
|
||||
name: 'members',
|
||||
title: 'Members',
|
||||
component: <ManageMembers />,
|
||||
admin: true,
|
||||
admin: true
|
||||
},
|
||||
{
|
||||
name: "notification",
|
||||
title: "Notification",
|
||||
component: <Notifications />,
|
||||
},
|
||||
],
|
||||
name: 'notification',
|
||||
title: 'Notification',
|
||||
component: <Notifications />
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "User",
|
||||
title: 'User',
|
||||
items: [
|
||||
{
|
||||
name: "my_account",
|
||||
title: "My Account",
|
||||
component: <MyAccount />,
|
||||
},
|
||||
],
|
||||
name: 'my_account',
|
||||
title: 'My Account',
|
||||
component: <MyAccount />
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Configuration",
|
||||
title: 'Configuration',
|
||||
items: [
|
||||
{
|
||||
name: "firebase",
|
||||
title: "Firebase",
|
||||
component: <ConfigFirebase />,
|
||||
name: 'firebase',
|
||||
title: 'Firebase',
|
||||
component: <ConfigFirebase />
|
||||
},
|
||||
{
|
||||
name: "agora",
|
||||
title: "Agora",
|
||||
component: <ConfigAgora />,
|
||||
name: 'agora',
|
||||
title: 'Agora',
|
||||
component: <ConfigAgora />
|
||||
},
|
||||
{
|
||||
name: "smtp",
|
||||
title: "SMTP",
|
||||
component: <ConfigSMTP />,
|
||||
name: 'smtp',
|
||||
title: 'SMTP',
|
||||
component: <ConfigSMTP />
|
||||
},
|
||||
{
|
||||
name: 'social_login',
|
||||
title: 'Social Login',
|
||||
component: <Logins />
|
||||
}
|
||||
],
|
||||
admin: true,
|
||||
admin: true
|
||||
},
|
||||
{
|
||||
title: "About",
|
||||
title: 'About',
|
||||
items: [
|
||||
{
|
||||
name: "faq",
|
||||
title: "FAQ",
|
||||
component: <FAQ />,
|
||||
name: 'faq',
|
||||
title: 'FAQ',
|
||||
component: <FAQ />
|
||||
},
|
||||
{
|
||||
name: "terms",
|
||||
title: "Terms & Privacy",
|
||||
component: "Terms & Privacy",
|
||||
name: 'terms',
|
||||
title: 'Terms & Privacy',
|
||||
component: 'Terms & Privacy'
|
||||
},
|
||||
{
|
||||
name: "feedback",
|
||||
title: "Feedback",
|
||||
component: "feedback",
|
||||
},
|
||||
],
|
||||
},
|
||||
name: 'feedback',
|
||||
title: 'Feedback',
|
||||
component: 'feedback'
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
const useNavs = () => {
|
||||
const loginUser = useSelector((store) => {
|
||||
|
||||
@@ -1,33 +1,29 @@
|
||||
/* eslint-disable no-undef */
|
||||
import { useEffect } from "react";
|
||||
import { useGetOpenidMutation } from "../../app/services/auth";
|
||||
import solidSvg from "../../assets/icons/solid.svg?url";
|
||||
import { StyledSocialButton } from "./styled";
|
||||
import { useEffect } from 'react';
|
||||
import { useGetOpenidMutation } from '../../app/services/auth';
|
||||
import solidSvg from '../../assets/icons/solid.svg?url';
|
||||
import { StyledSocialButton } from './styled';
|
||||
|
||||
export default function SolidLoginButton() {
|
||||
export default function SolidLoginButton({ issuers }) {
|
||||
const [getOpenId, { data, isLoading, isSuccess }] = useGetOpenidMutation();
|
||||
|
||||
const handleSolidLogin = () => {
|
||||
getOpenId({
|
||||
// issuer: "solidweb.org",
|
||||
issuer: "broker.pod.inrupt.com",
|
||||
redirect_uri: `${location.origin}/#/login`,
|
||||
issuer: issuers[0],
|
||||
redirect_uri: `${location.origin}/#/login`
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
if (isSuccess) {
|
||||
console.log("wtf", data);
|
||||
console.log('wtf', data);
|
||||
const { url } = data;
|
||||
location.href = url;
|
||||
}
|
||||
}, [data, isSuccess]);
|
||||
|
||||
return (
|
||||
<StyledSocialButton
|
||||
disabled={isLoading}
|
||||
onClick={handleSolidLogin}
|
||||
href="#"
|
||||
>
|
||||
<StyledSocialButton disabled={isLoading} onClick={handleSolidLogin} href="#">
|
||||
<img src={solidSvg} className="icon" alt="solid icon" />
|
||||
{isLoading ? `Redirecting...` : `Sign in with Solid`}
|
||||
</StyledSocialButton>
|
||||
|
||||
+37
-37
@@ -1,36 +1,38 @@
|
||||
/* eslint-disable no-undef */
|
||||
import { useState, useEffect } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import toast from "react-hot-toast";
|
||||
import BASE_URL from "../../app/config";
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import toast from 'react-hot-toast';
|
||||
import BASE_URL from '../../app/config';
|
||||
// import web3 from "web3";
|
||||
import StyledWrapper from "./styled";
|
||||
import MetamaskLoginButton from "./MetamaskLoginButton";
|
||||
import SolidLoginButton from "./SolidLoginButton";
|
||||
import Input from "../../common/component/styled/Input";
|
||||
import Button from "../../common/component/styled/Button";
|
||||
import GoogleLoginButton from "./GoogleLoginButton";
|
||||
import { useLoginMutation } from "../../app/services/auth";
|
||||
import { setAuthData } from "../../app/slices/auth.data";
|
||||
import StyledWrapper from './styled';
|
||||
import MetamaskLoginButton from './MetamaskLoginButton';
|
||||
import SolidLoginButton from './SolidLoginButton';
|
||||
import Input from '../../common/component/styled/Input';
|
||||
import Button from '../../common/component/styled/Button';
|
||||
import GoogleLoginButton from './GoogleLoginButton';
|
||||
import { useLoginMutation } from '../../app/services/auth';
|
||||
import { useGetLoginConfigQuery } from '../../app/services/server';
|
||||
import { setAuthData } from '../../app/slices/auth.data';
|
||||
|
||||
export default function LoginPage() {
|
||||
const [login, { data, isSuccess, isLoading, error }] = useLoginMutation();
|
||||
const { data: loginConfig, isSuccess: loginConfigSuccess } = useGetLoginConfigQuery();
|
||||
const navigateTo = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const [input, setInput] = useState({
|
||||
email: "",
|
||||
password: "",
|
||||
email: '',
|
||||
password: ''
|
||||
});
|
||||
useEffect(() => {
|
||||
const query = new URLSearchParams(location.search);
|
||||
const code = query.get("code");
|
||||
const state = query.get("state");
|
||||
const code = query.get('code');
|
||||
const state = query.get('state');
|
||||
if (code && state) {
|
||||
login({
|
||||
code,
|
||||
state,
|
||||
type: "oidc",
|
||||
type: 'oidc'
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
@@ -39,17 +41,17 @@ export default function LoginPage() {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
switch (error.status) {
|
||||
case "PARSING_ERROR":
|
||||
case 'PARSING_ERROR':
|
||||
toast.error(error.data);
|
||||
break;
|
||||
case 401:
|
||||
toast.error("username or password incorrect");
|
||||
toast.error('username or password incorrect');
|
||||
break;
|
||||
case 404:
|
||||
toast.error("account not exsit");
|
||||
toast.error('account not exsit');
|
||||
break;
|
||||
default:
|
||||
toast.error("something error");
|
||||
toast.error('something error');
|
||||
break;
|
||||
}
|
||||
return;
|
||||
@@ -58,19 +60,19 @@ export default function LoginPage() {
|
||||
useEffect(() => {
|
||||
if (isSuccess && data) {
|
||||
// 更新本地认证信息
|
||||
console.log("login data", data);
|
||||
toast.success("login success");
|
||||
console.log('login data', data);
|
||||
toast.success('login success');
|
||||
dispatch(setAuthData(data));
|
||||
navigateTo("/");
|
||||
navigateTo('/');
|
||||
}
|
||||
}, [isSuccess, data]);
|
||||
|
||||
const handleLogin = (evt) => {
|
||||
evt.preventDefault();
|
||||
console.log("wtf", input);
|
||||
console.log('wtf', input);
|
||||
login({
|
||||
...input,
|
||||
type: "password",
|
||||
type: 'password'
|
||||
});
|
||||
};
|
||||
|
||||
@@ -84,15 +86,13 @@ export default function LoginPage() {
|
||||
});
|
||||
};
|
||||
const { email, password } = input;
|
||||
if (!loginConfigSuccess) return null;
|
||||
const { google: enableGoogleLogin, metamask: enableMetamaskLogin, oidc } = loginConfig;
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<div className="form">
|
||||
<div className="tips">
|
||||
<img
|
||||
src={`${BASE_URL}/resource/organization/logo`}
|
||||
alt="logo"
|
||||
className="logo"
|
||||
/>
|
||||
<img src={`${BASE_URL}/resource/organization/logo`} alt="logo" className="logo" />
|
||||
<h2 className="title">Login to Rustchat</h2>
|
||||
<span className="desc">Please enter your details.</span>
|
||||
</div>
|
||||
@@ -117,13 +117,13 @@ export default function LoginPage() {
|
||||
placeholder="Enter your password"
|
||||
/>
|
||||
<Button type="submit" disabled={isLoading}>
|
||||
{isLoading ? "Signing" : `Sign in`}
|
||||
{isLoading ? 'Signing' : `Sign in`}
|
||||
</Button>
|
||||
</form>
|
||||
<hr className="or" />
|
||||
<GoogleLoginButton login={login} />
|
||||
<MetamaskLoginButton login={login} />
|
||||
<SolidLoginButton />
|
||||
{(enableGoogleLogin || enableMetamaskLogin || oidc.length > 0) && <hr className="or" />}
|
||||
{enableGoogleLogin && <GoogleLoginButton login={login} />}
|
||||
{enableMetamaskLogin && <MetamaskLoginButton login={login} />}
|
||||
{oidc.length > 0 && <SolidLoginButton issuers={oidc} />}
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user