Skip to content

Commit 1206742

Browse files
committed
feat: 🎸 Implemented login/logout in the manager app example
1 parent 94f3073 commit 1206742

File tree

5 files changed

+45
-41
lines changed

5 files changed

+45
-41
lines changed

‎examples/manager/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const App = () => {
2727
tabs={[
2828
{
2929
id: 0,
30-
title: 'Authorization',
30+
title: 'Access',
3131
active: true,
3232
},
3333
{

‎examples/manager/src/components/LoginWidget.tsx

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { createAdminSignature } from '../../../../src/node/api/client.js';
66
import { Tabs, TabPanel } from './Tabs.js';
77

88
export const LoginWidget = () => {
9-
const { isAuth, login, setConfig, resetAuth } = useConfig();
9+
const { isAuth, login, setAuth, resetAuth } = useConfig();
1010
const { node, nodeConnected } = useNode();
1111
const { isConnected, walletClient } = useWallet();
1212
const [selectedTab, setSelectedTab] = useState<number>(0);
@@ -66,24 +66,42 @@ export const LoginWidget = () => {
6666
});
6767
}, [node, name, handleSignature]);
6868

69-
const handleAdminAction = useCallback(async () => {
69+
const handleLogout = useCallback(async () => {
7070
try {
71+
setError(undefined);
72+
setMessage(undefined);
73+
7174
if (!node) {
7275
throw new Error('Not connected to the Node');
7376
}
7477

78+
await node.user.logout.mutate();
79+
resetAuth();
80+
} catch (error) {
81+
console.log(error);
82+
setError((error as Error).message || 'Unknown logout error');
83+
}
84+
}, [node, resetAuth]);
85+
86+
const handleAdminAction = useCallback(async () => {
87+
try {
7588
setError(undefined);
7689
setMessage(undefined);
7790

91+
if (!node) {
92+
throw new Error('Not connected to the Node');
93+
}
94+
7895
switch (adminAction) {
7996
case 'register':
8097
await handleAdminRegister();
81-
setConfig({ login: name });
8298
setAdminAction('login');
8399
setMessage(`Admin "${name}" successfully registered. Please log in.`);
100+
setAuth(name);
84101
break;
85102
case 'login':
86103
await handleAdminLogin();
104+
setAuth(name);
87105
break;
88106
default:
89107
throw new Error('Unknown admin action');
@@ -92,17 +110,18 @@ export const LoginWidget = () => {
92110
console.log(error);
93111
setError((error as Error).message || 'Unknown login error');
94112
}
95-
}, [
96-
node,
97-
adminAction,
98-
name,
99-
setConfig,
100-
handleAdminRegister,
101-
handleAdminLogin,
102-
]);
113+
}, [node, adminAction, name, handleAdminRegister, setAuth, handleAdminLogin]);
103114

104115
return (
105116
<>
117+
{isAuth &&
118+
<div>
119+
<div>Welcome {login ?? 'user'}</div>
120+
<div>
121+
<button onClick={handleLogout}>Log Out</button>
122+
</div>
123+
</div>
124+
}
106125
<Tabs
107126
tabs={[
108127
{
@@ -118,7 +137,6 @@ export const LoginWidget = () => {
118137
onChange={setSelectedTab}
119138
/>
120139
<TabPanel id={0} activeTab={selectedTab}>
121-
{isAuth && <div>Welcome {login ?? 'user'}</div>}
122140
{!isAuth && nodeConnected && (
123141
<div style={{ marginTop: 20 }}>
124142
<form
@@ -192,14 +210,6 @@ export const LoginWidget = () => {
192210
</div>
193211
</div>
194212
)}
195-
{isAuth && (
196-
<div>
197-
<div>Welcome {login ?? 'user'}</div>
198-
<div>
199-
<button onClick={() => resetAuth()}>Log Out</button>
200-
</div>
201-
</div>
202-
)}
203213
</TabPanel>
204214

205215
{message && <div style={{ marginTop: 20 }}>✅ {message}</div>}

‎examples/manager/src/providers/ConfigProvider/ConfigProviderContext.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { createContext, useContext } from 'react';
2-
import { HTTPHeaders } from '@trpc/client';
32

43
export const APP_CONFIG_KEY = 'appConfig';
54

65
export interface AppConfig {
76
nodeHost?: string;
8-
accessToken?: string;
97
login?: string;
108
}
119

@@ -14,7 +12,6 @@ export interface ConfigContextData extends AppConfig {
1412
setConfig(config: AppConfig): void;
1513
setAuth(accessToken: string): void;
1614
resetAuth(): void;
17-
getAuthHeaders(): HTTPHeaders;
1815
isAuth: boolean;
1916
}
2017

‎examples/manager/src/providers/ConfigProvider/index.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export const ConfigProvider = ({ children }: PropsWithChildren) => {
1616
const [config, setConfig] = useState<AppConfig>({});
1717
const [error, setError] = useState<string | undefined>();
1818

19-
const isAuth = useMemo(() => Boolean(config.accessToken), [config]);
19+
const isAuth = useMemo(() => Boolean(config.login), [config]);
2020

2121
const hydrate = useCallback((config: AppConfig) => {
2222
try {
@@ -55,22 +55,16 @@ export const ConfigProvider = ({ children }: PropsWithChildren) => {
5555
...config,
5656
...data,
5757
}),
58-
setAuth: (accessToken: string) =>
58+
setAuth: (login: string) =>
5959
setConfig({
6060
...config,
61-
accessToken,
61+
login,
6262
}),
6363
resetAuth: () =>
6464
setConfig({
6565
...config,
66-
accessToken: undefined,
6766
login: undefined,
6867
}),
69-
getAuthHeaders: () => ({
70-
authorization: config.accessToken
71-
? `Bearer ${config.accessToken}`
72-
: '',
73-
}),
7468
isAuth,
7569
configError: error,
7670
}}

‎examples/manager/src/providers/NodeProvider/index.tsx

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@ import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
22
import superjson from 'superjson';
33
import { PropsWithChildren, useState, useEffect } from 'react';
44
import { NodeContext } from './NodeProviderContext';
5-
import {
6-
ACCESS_TOKEN_NAME,
7-
accessTokenLink,
8-
} from '../../../../../src/node/api/client.js';
5+
import { unauthorizedLink } from '../../../../../src/node/api/client.js';
96
import type { AppRouter } from '../../../../../src/node/api/index.js';
107
import { useConfig } from '../ConfigProvider/ConfigProviderContext.js';
118

129
export const NodeProvider = ({ children }: PropsWithChildren) => {
13-
const { nodeHost, setAuth, getAuthHeaders } = useConfig();
10+
const { nodeHost, setAuth, resetAuth } = useConfig();
1411
const [node, setNode] = useState<
1512
ReturnType<typeof createTRPCProxyClient<AppRouter>> | undefined
1613
>();
@@ -38,10 +35,16 @@ export const NodeProvider = ({ children }: PropsWithChildren) => {
3835
const tRpcNode = createTRPCProxyClient<AppRouter>({
3936
transformer: superjson,
4037
links: [
41-
accessTokenLink(ACCESS_TOKEN_NAME, setAuth),
38+
unauthorizedLink(resetAuth),
4239
httpBatchLink({
4340
url: nodeHost,
44-
headers: getAuthHeaders,
41+
fetch(url, options) {
42+
return fetch(url, {
43+
...options,
44+
// allows to send cookies to the server
45+
credentials: 'include',
46+
});
47+
},
4548
}),
4649
],
4750
});
@@ -65,7 +68,7 @@ export const NodeProvider = ({ children }: PropsWithChildren) => {
6568
return () => {
6669
stopClient();
6770
};
68-
}, [getAuthHeaders, setAuth, nodeHost]);
71+
}, [nodeHost, setAuth, resetAuth]);
6972

7073
return (
7174
<NodeContext.Provider

0 commit comments

Comments
 (0)