Skip to content

Commit 67af120

Browse files
update
1 parent 1ff841b commit 67af120

File tree

17 files changed

+409
-75
lines changed

17 files changed

+409
-75
lines changed

webnext/src/pages/PasswordForm/PasswordFormPage.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ export const PasswordFormPage = () => {
167167
<field.FormInput
168168
mapError={mapPasswordFieldError}
169169
label={m.password_form_labels_password()}
170+
type="password"
170171
required
171172
/>
172173
)}
@@ -178,7 +179,11 @@ export const PasswordFormPage = () => {
178179
}}
179180
>
180181
{(field) => (
181-
<field.FormInput label={m.password_form_labels_repeat()} required />
182+
<field.FormInput
183+
label={m.password_form_labels_repeat()}
184+
type="password"
185+
required
186+
/>
182187
)}
183188
</form.AppField>
184189
<CheckList form={form} />

webnext/src/routeTree.gen.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { Route as IndexRouteImport } from './routes/index'
1818
import { Route as PasswordIndexRouteImport } from './routes/password/index'
1919
import { Route as PasswordSentRouteImport } from './routes/password/sent'
2020
import { Route as PasswordFinishRouteImport } from './routes/password/finish'
21+
import { Route as OpenidCallbackRouteImport } from './routes/openid/callback'
2122

2223
const TestRoute = TestRouteImport.update({
2324
id: '/test',
@@ -64,6 +65,11 @@ const PasswordFinishRoute = PasswordFinishRouteImport.update({
6465
path: '/password/finish',
6566
getParentRoute: () => rootRouteImport,
6667
} as any)
68+
const OpenidCallbackRoute = OpenidCallbackRouteImport.update({
69+
id: '/openid/callback',
70+
path: '/openid/callback',
71+
getParentRoute: () => rootRouteImport,
72+
} as any)
6773

6874
export interface FileRoutesByFullPath {
6975
'/': typeof IndexRoute
@@ -72,6 +78,7 @@ export interface FileRoutesByFullPath {
7278
'/enrollment-start': typeof EnrollmentStartRoute
7379
'/password-reset': typeof PasswordResetRoute
7480
'/test': typeof TestRoute
81+
'/openid/callback': typeof OpenidCallbackRoute
7582
'/password/finish': typeof PasswordFinishRoute
7683
'/password/sent': typeof PasswordSentRoute
7784
'/password': typeof PasswordIndexRoute
@@ -83,6 +90,7 @@ export interface FileRoutesByTo {
8390
'/enrollment-start': typeof EnrollmentStartRoute
8491
'/password-reset': typeof PasswordResetRoute
8592
'/test': typeof TestRoute
93+
'/openid/callback': typeof OpenidCallbackRoute
8694
'/password/finish': typeof PasswordFinishRoute
8795
'/password/sent': typeof PasswordSentRoute
8896
'/password': typeof PasswordIndexRoute
@@ -95,6 +103,7 @@ export interface FileRoutesById {
95103
'/enrollment-start': typeof EnrollmentStartRoute
96104
'/password-reset': typeof PasswordResetRoute
97105
'/test': typeof TestRoute
106+
'/openid/callback': typeof OpenidCallbackRoute
98107
'/password/finish': typeof PasswordFinishRoute
99108
'/password/sent': typeof PasswordSentRoute
100109
'/password/': typeof PasswordIndexRoute
@@ -108,6 +117,7 @@ export interface FileRouteTypes {
108117
| '/enrollment-start'
109118
| '/password-reset'
110119
| '/test'
120+
| '/openid/callback'
111121
| '/password/finish'
112122
| '/password/sent'
113123
| '/password'
@@ -119,6 +129,7 @@ export interface FileRouteTypes {
119129
| '/enrollment-start'
120130
| '/password-reset'
121131
| '/test'
132+
| '/openid/callback'
122133
| '/password/finish'
123134
| '/password/sent'
124135
| '/password'
@@ -130,6 +141,7 @@ export interface FileRouteTypes {
130141
| '/enrollment-start'
131142
| '/password-reset'
132143
| '/test'
144+
| '/openid/callback'
133145
| '/password/finish'
134146
| '/password/sent'
135147
| '/password/'
@@ -142,6 +154,7 @@ export interface RootRouteChildren {
142154
EnrollmentStartRoute: typeof EnrollmentStartRoute
143155
PasswordResetRoute: typeof PasswordResetRoute
144156
TestRoute: typeof TestRoute
157+
OpenidCallbackRoute: typeof OpenidCallbackRoute
145158
PasswordFinishRoute: typeof PasswordFinishRoute
146159
PasswordSentRoute: typeof PasswordSentRoute
147160
PasswordIndexRoute: typeof PasswordIndexRoute
@@ -212,6 +225,13 @@ declare module '@tanstack/react-router' {
212225
preLoaderRoute: typeof PasswordFinishRouteImport
213226
parentRoute: typeof rootRouteImport
214227
}
228+
'/openid/callback': {
229+
id: '/openid/callback'
230+
path: '/openid/callback'
231+
fullPath: '/openid/callback'
232+
preLoaderRoute: typeof OpenidCallbackRouteImport
233+
parentRoute: typeof rootRouteImport
234+
}
215235
}
216236
}
217237

@@ -222,6 +242,7 @@ const rootRouteChildren: RootRouteChildren = {
222242
EnrollmentStartRoute: EnrollmentStartRoute,
223243
PasswordResetRoute: PasswordResetRoute,
224244
TestRoute: TestRoute,
245+
OpenidCallbackRoute: OpenidCallbackRoute,
225246
PasswordFinishRoute: PasswordFinishRoute,
226247
PasswordSentRoute: PasswordSentRoute,
227248
PasswordIndexRoute: PasswordIndexRoute,

webnext/src/routes/client-setup.tsx

Lines changed: 52 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,71 @@
11
import { createFileRoute, redirect } from '@tanstack/react-router';
2+
import z from 'zod';
23
import { ConfigureClientPage } from '../pages/enrollment/ConfigureClient/ConfigureClientPage';
4+
import { api } from '../shared/api/api';
35
import type { EnrollmentStartResponse } from '../shared/api/types';
6+
import { isPresent } from '../shared/defguard-ui/utils/isPresent';
47
import { useEnrollmentStore } from '../shared/hooks/useEnrollmentStore';
58

6-
const _fetchDesktop = async () => {
7-
const _resp = await fetch('https://api.git.com/repos/defguard/client/releases/latest', {
8-
method: 'GET',
9-
});
10-
};
9+
const schema = z.object({
10+
code: z.string().trim().optional(),
11+
state: z.string().trim().optional(),
12+
});
1113

1214
export const Route = createFileRoute('/client-setup')({
1315
component: ConfigureClientPage,
14-
beforeLoad: () => {
16+
validateSearch: schema,
17+
loaderDeps: ({ search }) => ({ search }),
18+
beforeLoad: ({ search }) => {
19+
// if openId flow just pass the search to the context
20+
if (search && isPresent(search.code) && isPresent(search.state)) {
21+
return {
22+
openid: {
23+
code: search.code,
24+
state: search.state,
25+
},
26+
};
27+
}
28+
// if not openId then expect state to be in session
1529
const state = useEnrollmentStore.getState();
1630
if (state.token === undefined || state.enrollmentData === undefined) {
1731
throw redirect({
1832
to: '/enrollment-start',
1933
replace: true,
2034
});
2135
}
36+
return {
37+
openid: undefined,
38+
};
2239
},
23-
loader: () => {
40+
loader: async ({ context: { openid } }) => {
41+
if (openid) {
42+
try {
43+
const openIdResponse = await api.openId.enrollmentCallback.callbackFn({
44+
data: {
45+
code: openid.code,
46+
state: openid.state,
47+
type: 'enrollment',
48+
},
49+
});
50+
51+
const enrollResponse = await api.enrollment.start.callbackFn({
52+
data: {
53+
token: openIdResponse.data.token,
54+
},
55+
});
56+
57+
return {
58+
token: openIdResponse.data.token,
59+
enrollmentData: enrollResponse.data,
60+
};
61+
} catch (e) {
62+
console.error(e);
63+
throw redirect({
64+
to: '/',
65+
replace: true,
66+
});
67+
}
68+
}
2469
const state = useEnrollmentStore.getState();
2570
return {
2671
token: state.token as string,
Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,21 @@
1-
import { createFileRoute, redirect } from '@tanstack/react-router';
1+
import { createFileRoute } from '@tanstack/react-router';
22
import type { AxiosError } from 'axios';
33
import { EnrollmentStartPage } from '../pages/enrollment/EnrollmentStart/EnrollmentStartPage';
44
import { api } from '../shared/api/api';
55

66
export const Route = createFileRoute('/enrollment-start')({
77
component: EnrollmentStartPage,
88
loader: async () => {
9+
// workaround cuz this endpoint throws 404 when openid is not configured
910
const resp = await api.openId.authInfo
1011
.callbackFn({
1112
data: {
1213
type: 'enrollment',
1314
},
1415
})
1516
.catch((e: AxiosError) => {
16-
//FIXME: should redirect
17-
if (e.status !== 500) {
18-
throw redirect({
19-
to: '/',
20-
replace: true,
21-
});
22-
}
17+
console.error(e);
2318
});
24-
//FIXME
2519
return resp?.data;
2620
},
2721
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { createFileRoute, redirect } from '@tanstack/react-router';
2+
import z from 'zod';
3+
4+
const schema = z.object({
5+
state: z.string().trim().min(1),
6+
code: z.string().trim().min(1),
7+
});
8+
9+
// this route exists only for redirect, this is done to maintain compatibility with old UI and retain existing links
10+
export const Route = createFileRoute('/openid/callback')({
11+
component: RouteComponent,
12+
validateSearch: schema,
13+
loaderDeps: ({ search }) => ({ search }),
14+
beforeLoad: ({ search }) => {
15+
throw redirect({
16+
to: '/client-setup',
17+
search: search,
18+
});
19+
},
20+
});
21+
22+
function RouteComponent() {
23+
return null;
24+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import './style.scss';
2+
import clsx from 'clsx';
3+
import { isPresent } from '../../utils/isPresent';
4+
import { Icon } from '../Icon';
5+
import { InteractionBox } from '../InteractionBox/InteractionBox';
6+
import type { FieldBoxProps } from './types';
7+
8+
// generalized field box for components like Input, shouldn't be in layout on it's own
9+
export const FieldBox = ({
10+
children,
11+
disabled,
12+
error,
13+
className,
14+
boxRef,
15+
interactionRef,
16+
iconLeft,
17+
iconRight,
18+
size,
19+
onInteractionClick,
20+
...rest
21+
}: FieldBoxProps) => {
22+
const hasIconLeft = isPresent(iconLeft);
23+
const hasIconRight = isPresent(iconRight);
24+
return (
25+
<div
26+
className={clsx('field-box', className, `size-${size}`, {
27+
'grid-default': !hasIconLeft && !hasIconRight,
28+
'grid-left': hasIconLeft && !hasIconRight,
29+
'grid-right': hasIconRight && !hasIconLeft,
30+
'grid-both': hasIconLeft && hasIconRight,
31+
disabled,
32+
error,
33+
})}
34+
{...rest}
35+
>
36+
{hasIconLeft && <Icon icon={iconLeft} size={20} />}
37+
{children}
38+
{hasIconRight && (
39+
<InteractionBox
40+
disabled={disabled}
41+
iconSize={20}
42+
icon={iconRight}
43+
onClick={onInteractionClick}
44+
tabIndex={-1}
45+
/>
46+
)}
47+
</div>
48+
);
49+
};

0 commit comments

Comments
 (0)