Skip to content

Commit fbd9d21

Browse files
authored
Merge pull request #23 from Dialogue-Bot/DIAL-20-refesh-token-bot-client-serrver
Dial 20 refesh token bot client serrver
2 parents 1443761 + 72d47d3 commit fbd9d21

File tree

23 files changed

+219
-74
lines changed

23 files changed

+219
-74
lines changed

client/src/app.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { AppLayout, AuthLayout, SettingLayout } from '@/components/layouts';
1919
import { TChannelQuery } from './types/channel';
2020
import { queryStringToObject } from './utils';
2121
import { queryChannelsOption } from './lib/query-options/channel';
22+
import { ROUTES } from './constants';
2223

2324
export const router = createBrowserRouter([
2425
{
@@ -41,20 +42,20 @@ export const router = createBrowserRouter([
4142
Component: AuthLayout,
4243
children: [
4344
{
44-
path: '/login',
45+
path: ROUTES.AUTH.LOGIN,
4546
Component: Login,
4647
index: true,
4748
},
4849
{
49-
path: '/register',
50+
path: ROUTES.AUTH.REGISTER,
5051
Component: Register,
5152
},
5253
{
53-
path: '/forgot-password',
54+
path: ROUTES.AUTH.FORGOT_PASS,
5455
Component: ForgotPassword,
5556
},
5657
{
57-
path: '/set-password',
58+
path: ROUTES.AUTH.RESET_PASS,
5859
Component: SetPassword,
5960
},
6061
],
@@ -71,7 +72,7 @@ export const router = createBrowserRouter([
7172
});
7273

7374
if (!user) {
74-
return redirect(`/login?${url.toString()}`);
75+
return redirect(`${ROUTES.AUTH.LOGIN}?${url.toString()}`);
7576
}
7677

7778
useUserStore.getState().setUser(user);
@@ -80,14 +81,14 @@ export const router = createBrowserRouter([
8081
},
8182
children: [
8283
{
83-
path: '/dashboard',
84+
path: ROUTES.PRIVATE.DASHBOARD,
8485
index: true,
8586
loader: async () => {
86-
return redirect('/chatbots');
87+
return redirect(ROUTES.PRIVATE.CHAT_BOT.INDEX);
8788
},
8889
},
8990
{
90-
path: '/chatbots',
91+
path: ROUTES.PRIVATE.CHAT_BOT.INDEX,
9192
element: <div>a</div>,
9293
loader: () => {
9394
useAppLayoutStore
@@ -98,7 +99,7 @@ export const router = createBrowserRouter([
9899
},
99100
},
100101
{
101-
path: '/channels',
102+
path: ROUTES.PRIVATE.CHANNEL.INDEX,
102103
Component: Channels,
103104
loader: async ({ request }) => {
104105
const query: TChannelQuery = queryStringToObject(
@@ -117,7 +118,7 @@ export const router = createBrowserRouter([
117118
},
118119
},
119120
{
120-
path: '/settings',
121+
path: ROUTES.PRIVATE.SETTING.INDEX,
121122
Component: SettingLayout,
122123
loader: async () => {
123124
const data =
@@ -132,25 +133,25 @@ export const router = createBrowserRouter([
132133
},
133134
children: [
134135
{
135-
path: 'mail',
136+
path: ROUTES.PRIVATE.SETTING.MAIL,
136137
Component: Mail,
137138
},
138139
{
139-
path: 'profiles',
140+
path: ROUTES.PRIVATE.SETTING.PROFILES,
140141
Component: Profiles,
141142
},
142143
{
143144
index: true,
144145
loader: async () => {
145-
return redirect('/settings/profiles');
146+
return redirect(ROUTES.PRIVATE.SETTING.PROFILES);
146147
},
147148
},
148149
],
149150
},
150151
],
151152
},
152153
{
153-
path: '/',
154+
path: ROUTES.PUBLIC.LANDING_PAGE,
154155
element: <div>Hi</div>,
155156
},
156157
],

client/src/components/forms/channel.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { useQuery } from '@tanstack/react-query';
2222
import { queryChannelTypesOption } from '@/lib/query-options/channel';
2323
import { zodResolver } from '@hookform/resolvers/zod';
2424
import { ChannelType } from '@/types/channel';
25-
import { useEffect, useMemo } from 'react';
25+
import { useMemo } from 'react';
2626
import { useDidUpdate } from '@/hooks/use-did-update';
2727

2828
type Props = {
@@ -41,7 +41,10 @@ const ChannelForm = ({
4141
const form = useForm<TChannelInput>({
4242
resolver: zodResolver(schema),
4343
mode: 'onChange',
44-
defaultValues,
44+
defaultValues: {
45+
active: true,
46+
...defaultValues,
47+
},
4548
});
4649
const { data: types } = useQuery(queryChannelTypesOption);
4750

client/src/components/forms/setting-mail.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export const SettingMailForm = ({
6161
<Input
6262
{...field}
6363
placeholder={t('email.placeholder')}
64+
autoComplete="one-time-code"
6465
/>
6566
</FormControl>
6667
<FormMessage />
@@ -80,6 +81,7 @@ export const SettingMailForm = ({
8081
{...field}
8182
placeholder={t('password.placeholder')}
8283
type="password"
84+
autoComplete="one-time-code"
8385
/>
8486
</FormControl>
8587
<FormMessage />

client/src/components/pages/channels/data-toolbar.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import ChannelForm from '@/components/forms/channel';
22
import {
33
Button,
4-
Input,
54
Sheet,
6-
SheetClose,
75
SheetContent,
86
SheetDescription,
97
SheetFooter,
@@ -13,14 +11,10 @@ import {
1311
} from '@/components/ui';
1412
import { useCreateChannel } from '@/hooks/channel';
1513
import { useSearch } from '@/hooks/use-search';
16-
import React, { useState } from 'react';
14+
import { useState } from 'react';
1715
import { Trans, useTranslation } from 'react-i18next';
1816
import { Link } from 'react-router-dom';
1917

20-
type Props = {
21-
table: any;
22-
};
23-
2418
export const DataToolbar = () => {
2519
const { renderInput } = useSearch();
2620
const { t } = useTranslation(['common', 'channel']);

client/src/components/pages/channels/row-action.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { useBodyOverflow } from '@/hooks/use-body-overflow';
1919
import { TChannelWithChannelType } from '@/types/channel';
2020
import { Row } from '@tanstack/react-table';
2121
import { Link, MoreHorizontal } from 'lucide-react';
22-
import { useEffect, useState } from 'react';
22+
import { useState } from 'react';
2323
import { Trans, useTranslation } from 'react-i18next';
2424

2525
type Props = {

client/src/constants/index.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,31 @@ export const ENDPOINTS = {
3131
TYPES: '/channel/types',
3232
},
3333
};
34+
35+
export const ROUTES = {
36+
AUTH: {
37+
LOGIN: '/login',
38+
REGISTER: '/register',
39+
FORGOT_PASS: '/forgot-password',
40+
RESET_PASS: '/set-password',
41+
},
42+
PUBLIC: {
43+
LANDING_PAGE: '/',
44+
},
45+
PRIVATE: {
46+
DASHBOARD: '/dashboard',
47+
CHANNEL: {
48+
INDEX: '/channels',
49+
CREATE: '/channels/create',
50+
EDIT: '/channels/edit',
51+
},
52+
CHAT_BOT: {
53+
INDEX: '/chatbots',
54+
},
55+
SETTING: {
56+
INDEX: '/settings',
57+
MAIL: '/settings/email',
58+
PROFILES: '/settings/profiles',
59+
},
60+
},
61+
};

client/src/lib/http-client.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { auth } from '@/apis/auth';
2+
import { ROUTES } from '@/constants';
13
import { ELang } from '@/types/share';
24
import axios from 'axios';
35

@@ -27,7 +29,36 @@ http_client.interceptors.response.use(
2729
function (response) {
2830
return response.data;
2931
},
30-
function (error) {
32+
async function (error) {
33+
const originalRequest = error.config;
34+
35+
if (
36+
Object.values(ROUTES.AUTH).some((route) =>
37+
window.location.pathname.includes(route)
38+
)
39+
) {
40+
return Promise.reject(error);
41+
}
42+
43+
if (error.response?.status === 401 && !originalRequest._retry) {
44+
try {
45+
originalRequest._retry = true;
46+
47+
const tokens = await auth.refreshToken().then((r) => {
48+
return r.data;
49+
});
50+
51+
http_client.defaults.headers.common['Authorization'] =
52+
`Bearer ${tokens?.accessToken}`;
53+
54+
return http_client(originalRequest);
55+
} catch (error) {
56+
const prevHref = window.location.href;
57+
window.location.href = `/login?redirect=${prevHref}`;
58+
return Promise.reject(error);
59+
}
60+
}
61+
3162
return Promise.reject(error);
3263
}
3364
);

client/src/lib/schema/channel.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { channelApi } from '@/apis/channel';
22
import { ChannelType } from '@/types/channel';
3+
import { useQuery } from '@tanstack/react-query';
34
import { useTranslation } from 'react-i18next';
45
import * as z from 'zod';
6+
import { queryChannelTypesOption } from '../query-options/channel';
57

68
export const useChannelSchema = () => {
79
const { t } = useTranslation('forms');
10+
const { data: types } = useQuery(queryChannelTypesOption);
811

912
return z
1013
.object({
@@ -33,9 +36,11 @@ export const useChannelSchema = () => {
3336
})
3437
.superRefine(async (data, ctx) => {
3538
if (data.credentials) {
36-
const type = await channelApi
37-
.getChannelType(data.channelTypeId)
38-
.then((r) => r.data);
39+
const type = types?.find((type) => type.id === data.channelTypeId);
40+
41+
if (!type) {
42+
return;
43+
}
3944

4045
switch (type.name) {
4146
case ChannelType.MESSENGER:

client/src/pages/channels.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export const Channels = () => {
3030
<DataTable
3131
columns={cols}
3232
data={data.items || []}
33-
renderToolbar={(table) => <DataToolbar />}
33+
renderToolbar={() => <DataToolbar />}
3434
opts={{
3535
state: {
3636
sorting,

server/src/config/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,6 @@ export const {
3030
SIGNATURE_SECRET,
3131
PUBLIC_DOMAIN,
3232
BOT_ENDPOINT,
33+
MAIL_USER,
34+
MAIL_PASS,
3335
} = process.env;

0 commit comments

Comments
 (0)