Skip to content

Commit 18d3fe3

Browse files
committed
Convert remaining identifier javascript code to typescript
Add types for relevant annotations with packages.
1 parent 5fabe20 commit 18d3fe3

File tree

13 files changed

+153
-80
lines changed

13 files changed

+153
-80
lines changed

identifier/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"axios": "^0.22.0",
1111
"classnames": "^2.3.2",
1212
"glob": "^8.1.0",
13+
"history": "^5.3.0",
1314
"i18next": "^21.10.0",
1415
"i18next-browser-languagedetector": "^6.1.8",
1516
"i18next-http-backend": "^1.4.5",

identifier/src/actions/common.js renamed to identifier/src/actions/common.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import axios from 'axios';
1+
import axios, { AxiosError, AxiosResponse } from 'axios';
22

3-
import { newHelloRequest } from '../models/hello';
3+
import { HelloQuery, newHelloRequest } from '../models/hello';
44
import { withClientRequestState } from '../utils';
55
import {
66
ExtendedError,
@@ -10,8 +10,10 @@ import {
1010

1111
import { handleAxiosError } from './utils';
1212
import * as types from './types';
13+
import { Dispatch } from 'redux';
14+
import { AppDispatch, PromiseDispatch, RootState } from '../store';
1315

14-
export function receiveError(error) {
16+
export function receiveError(error?: ExtendedError | AxiosError<never> | null) {
1517
return {
1618
type: types.RECEIVE_ERROR,
1719
error
@@ -24,7 +26,7 @@ export function resetHello() {
2426
};
2527
}
2628

27-
export function receiveHello(hello) {
29+
export function receiveHello(hello: {success?: boolean, username: string, displayName?: string}) {
2830
const { success, username, displayName } = hello;
2931

3032
return {
@@ -37,12 +39,12 @@ export function receiveHello(hello) {
3739
}
3840

3941
export function executeHello() {
40-
return function(dispatch, getState) {
42+
return function(dispatch:Dispatch , getState: () => RootState) {
4143
dispatch(resetHello());
4244

4345
const { flow, query } = getState().common;
4446

45-
const r = withClientRequestState(newHelloRequest(flow, query));
47+
const r = withClientRequestState(newHelloRequest(flow as string, query as HelloQuery));
4648
return axios.post('./identifier/_/hello', r, {
4749
headers: {
4850
'Kopano-Konnect-XSRF': '1'
@@ -60,7 +62,7 @@ export function executeHello() {
6062
};
6163
default:
6264
// error.
63-
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response);
65+
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response as AxiosResponse<never>);
6466
}
6567
}).then(response => {
6668
if (response.state !== r.state) {
@@ -78,7 +80,7 @@ export function executeHello() {
7880
}
7981

8082
export function retryHello() {
81-
return function(dispatch) {
83+
return function(dispatch: PromiseDispatch) {
8284
dispatch(receiveError(null));
8385

8486
return dispatch(executeHello());
@@ -91,15 +93,15 @@ export function requestLogoff() {
9193
};
9294
}
9395

94-
export function receiveLogoff(state) {
96+
export function receiveLogoff(state: boolean) {
9597
return {
9698
type: types.RECEIVE_LOGOFF,
9799
state
98100
};
99101
}
100102

101103
export function executeLogoff() {
102-
return function(dispatch) {
104+
return function(dispatch: AppDispatch) {
103105
dispatch(resetHello());
104106
dispatch(requestLogoff());
105107

@@ -115,7 +117,7 @@ export function executeLogoff() {
115117
return response.data;
116118
default:
117119
// error.
118-
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response);
120+
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response as AxiosResponse<never>);
119121
}
120122
}).then(response => {
121123
if (response.state !== r.state) {

identifier/src/actions/login.js renamed to identifier/src/actions/login.ts

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import axios from 'axios';
1+
import axios, { AxiosResponse } from 'axios';
22
import queryString from 'query-string';
33

4-
import { newHelloRequest } from '../models/hello';
4+
import { HelloQuery, newHelloRequest } from '../models/hello';
55
import { withClientRequestState } from '../utils';
66
import {
77
ExtendedError,
@@ -15,35 +15,37 @@ import {
1515
import * as types from './types';
1616
import { receiveHello } from './common';
1717
import { handleAxiosError } from './utils';
18+
import { AppDispatch, PromiseDispatch, RootState } from '../store';
19+
import { History } from "history";
1820

1921
// Modes for logon.
2022
export const ModeLogonUsernameEmptyPasswordCookie = '0';
2123
export const ModeLogonUsernamePassword = '1';
2224

23-
export function updateInput(name, value) {
25+
export function updateInput(name: string, value?: string | null) {
2426
return {
2527
type: types.UPDATE_INPUT,
2628
name,
2729
value
2830
};
2931
}
3032

31-
export function receiveValidateLogon(errors) {
33+
export function receiveValidateLogon(errors: Error | {[key: string]: Error}) {
3234
return {
3335
type: types.RECEIVE_VALIDATE_LOGON,
3436
errors
3537
};
3638
}
3739

38-
export function requestLogon(username, password) {
40+
export function requestLogon(username: string, password: string) {
3941
return {
4042
type: types.REQUEST_LOGON,
4143
username,
4244
password
4345
};
4446
}
4547

46-
export function receiveLogon(logon) {
48+
export function receiveLogon(logon: {success: boolean, errors: {http: Error}}) {
4749
const { success, errors } = logon;
4850

4951
return {
@@ -59,7 +61,7 @@ export function requestConsent(allow=false) {
5961
};
6062
}
6163

62-
export function receiveConsent(logon) {
64+
export function receiveConsent(logon: {success: boolean, errors: {http: Error}}) {
6365
const { success, errors } = logon;
6466

6567
return {
@@ -69,8 +71,8 @@ export function receiveConsent(logon) {
6971
};
7072
}
7173

72-
export function executeLogon(username, password, mode=ModeLogonUsernamePassword) {
73-
return function(dispatch, getState) {
74+
export function executeLogon(username: string, password: string, mode=ModeLogonUsernamePassword) {
75+
return function(dispatch: AppDispatch, getState: () => RootState) {
7476
dispatch(requestLogon(username, password));
7577
dispatch(receiveHello({
7678
username
@@ -96,7 +98,7 @@ export function executeLogon(username, password, mode=ModeLogonUsernamePassword)
9698

9799
const r = withClientRequestState({
98100
params: params,
99-
hello: newHelloRequest(flow, query)
101+
hello: newHelloRequest(flow as string, query as HelloQuery)
100102
});
101103
return axios.post('./identifier/_/logon', r, {
102104
headers: {
@@ -118,7 +120,7 @@ export function executeLogon(username, password, mode=ModeLogonUsernamePassword)
118120
};
119121
default:
120122
// error.
121-
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response);
123+
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response as AxiosResponse<never>);
122124
}
123125
}).then(response => {
124126
if (response.state !== r.state) {
@@ -151,7 +153,7 @@ export function executeLogon(username, password, mode=ModeLogonUsernamePassword)
151153
}
152154

153155
export function executeConsent(allow=false, scope='') {
154-
return function(dispatch, getState) {
156+
return function(dispatch: AppDispatch, getState: () => RootState) {
155157
dispatch(requestConsent(allow));
156158

157159
const { query } = getState().common;
@@ -181,7 +183,7 @@ export function executeConsent(allow=false, scope='') {
181183
};
182184
default:
183185
// error.
184-
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response);
186+
throw new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, response as AxiosResponse<never>);
185187
}
186188
}).then(response => {
187189
if (response.state !== r.state) {
@@ -205,10 +207,10 @@ export function executeConsent(allow=false, scope='') {
205207
};
206208
}
207209

208-
export function validateUsernamePassword(username, password, isSignedIn) {
209-
return function(dispatch) {
210+
export function validateUsernamePassword(username: string, password: string, isSignedIn: boolean) {
211+
return function(dispatch: AppDispatch) {
210212
return new Promise((resolve, reject) => {
211-
const errors = {};
213+
const errors:{[key: string]: Error} = {};
212214

213215
if (!username) {
214216
errors.username = new Error(ERROR_LOGIN_VALIDATE_MISSINGUSERNAME);
@@ -227,14 +229,14 @@ export function validateUsernamePassword(username, password, isSignedIn) {
227229
};
228230
}
229231

230-
export function executeLogonIfFormValid(username, password, isSignedIn) {
231-
return (dispatch) => {
232+
export function executeLogonIfFormValid(username: string, password: string, isSignedIn: boolean) {
233+
return (dispatch: PromiseDispatch) => {
232234
return dispatch(
233235
validateUsernamePassword(username, password, isSignedIn)
234236
).then(() => {
235237
const mode = isSignedIn ? ModeLogonUsernameEmptyPasswordCookie : ModeLogonUsernamePassword;
236238
return dispatch(executeLogon(username, password, mode));
237-
}).catch((errors) => {
239+
}).catch((errors: Error | {[key: string]:Error}) => {
238240
return {
239241
success: false,
240242
errors: errors
@@ -243,8 +245,9 @@ export function executeLogonIfFormValid(username, password, isSignedIn) {
243245
};
244246
}
245247

246-
export function advanceLogonFlow(success, history, done=false, extraQuery={}) {
247-
return (dispatch, getState) => {
248+
249+
export function advanceLogonFlow(success: boolean, history: History, done=false, extraQuery={}) {
250+
return (dispatch:AppDispatch, getState: () => RootState) => {
248251
if (!success) {
249252
return;
250253
}
@@ -256,16 +259,16 @@ export function advanceLogonFlow(success, history, done=false, extraQuery={}) {
256259
case 'oauth':
257260
case 'consent':
258261
case 'oidc':
259-
if (hello.details.flow !== flow) {
262+
if (hello?.details?.flow !== flow) {
260263
// Ignore requested flow if hello flow does not match.
261264
break;
262265
}
263266

264-
if (!done && hello.details.next === 'consent') {
267+
if (!done && hello?.details.next === 'consent') {
265268
history.replace(`/consent${history.location.search}${history.location.hash}`);
266269
return;
267270
}
268-
if (hello.details.continue_uri) {
271+
if (hello?.details.continue_uri) {
269272
q.prompt = 'none';
270273
window.location.replace(hello.details.continue_uri + '?' + queryString.stringify(q));
271274
return;
@@ -276,7 +279,7 @@ export function advanceLogonFlow(success, history, done=false, extraQuery={}) {
276279
default:
277280
// Legacy stupid modes.
278281
if (q.continue && q.continue.indexOf(document.location.origin) === 0) {
279-
window.location.replace(q.continue);
282+
window.location.replace(q.continue as string);
280283
return;
281284
}
282285
}
File renamed without changes.

identifier/src/actions/utils.js renamed to identifier/src/actions/utils.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1+
import { AxiosError } from 'axios';
12
import {
23
ExtendedError,
34
ERROR_HTTP_NETWORK_ERROR,
45
ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS
56
} from '../errors';
67

7-
export function handleAxiosError(error) {
8-
if (error.request) {
8+
export function handleAxiosError(error: AxiosError | ExtendedError) {
9+
if ((error as AxiosError).request) {
910
// Axios errors.
10-
if (error.response) {
11-
error = new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, error.response);
11+
if ((error as AxiosError).response) {
12+
error = new ExtendedError(ERROR_HTTP_UNEXPECTED_RESPONSE_STATUS, (error as AxiosError).response);
1213
} else {
1314
error = new ExtendedError(ERROR_HTTP_NETWORK_ERROR);
1415
}

identifier/src/errors/index.js renamed to identifier/src/errors/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/* eslint react/prop-types: 0 */
22

3+
import { AxiosResponse } from 'axios';
4+
import { TFunction } from 'i18next';
35
import { withTranslation } from 'react-i18next';
46

57
export const ERROR_LOGIN_VALIDATE_MISSINGUSERNAME = 'konnect.error.login.validate.missingUsername';
@@ -11,9 +13,9 @@ export const ERROR_HTTP_UNEXPECTED_RESPONSE_STATE = 'konnect.error.http.unexpect
1113

1214
// Error with values.
1315
export class ExtendedError extends Error {
14-
values = undefined;
16+
values: { [key: string]: string | null | undefined | Error } | null | undefined | AxiosResponse<never> = undefined;
1517

16-
constructor(message, values) {
18+
constructor(message: string, values?: { [key: string]: string | null | undefined | Error } | null | AxiosResponse<never>) {
1719
super(message);
1820
if (Error.captureStackTrace !== undefined) {
1921
Error.captureStackTrace(this, ExtendedError);
@@ -23,7 +25,7 @@ export class ExtendedError extends Error {
2325
}
2426

2527
// Component to translate error text with values.
26-
function ErrorMessageComponent(props) {
28+
function ErrorMessageComponent(props: { error?: { id: null | undefined | string, message: string | null | undefined, values: { [key: string] : string | boolean | Error } }, t: TFunction, values: {[key:string]: string | boolean} }): JSX.Element | null {
2729
const { error, t, values } = props;
2830

2931
if (!error) {
@@ -57,7 +59,7 @@ function ErrorMessageComponent(props) {
5759
}
5860

5961
const f = t;
60-
return f(messageDescriptor.defaultMessage, messageDescriptor.values);
62+
return f(messageDescriptor.defaultMessage ?? "", messageDescriptor.values);
6163
}
6264

6365
export const ErrorMessage = withTranslation()(ErrorMessageComponent);

identifier/src/models/hello.js renamed to identifier/src/models/hello.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
export function newHelloRequest(flow, query) {
2-
const r = {};
1+
export type HelloQuery = { scope?: string, client_id?: string, redirect_uri: string, id_token_hint?: string, max_age?: string,claims_scope?: string, prompt?: string }
2+
3+
4+
5+
export function newHelloRequest(flow: string, query: HelloQuery) {
6+
const r:{[key: string]: string} = {};
37

48
if (query.prompt) {
59
// TODO(longsleep): Validate prompt values?
610
r.prompt = query.prompt;
711
}
8-
9-
let selectedFlow = flow;
12+
13+
let selectedFlow: string | null = flow;
1014
switch (flow) {
1115
case 'oauth':
1216
case 'consent':

0 commit comments

Comments
 (0)