Skip to content

Commit c4adc3a

Browse files
authored
feature: retrieve access token (#68)
* feature: access token * feat: display date valid * style: prettify * test: remove switch button * refactor: NativeTokenData
1 parent 2f00675 commit c4adc3a

File tree

10 files changed

+86
-64
lines changed

10 files changed

+86
-64
lines changed

js-miniapp-bridge/src/common-bridge.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
} from './types/custom-permissions';
1414
import { ShareInfoType } from './types/share-info';
1515
import { ScreenOrientation } from './types/screen';
16+
import { NativeTokenData, AccessTokenData } from './types/token-data';
1617

1718
/** @internal */
1819
const mabMessageQueue: Callback[] = [];
@@ -263,6 +264,23 @@ export class MiniAppBridge {
263264
});
264265
}
265266

267+
/**
268+
* Get access token from native hostapp.
269+
*/
270+
getAccessToken() {
271+
return new Promise<AccessTokenData>((resolve, reject) => {
272+
return this.executor.exec(
273+
'getAccessToken',
274+
null,
275+
tokenData => {
276+
const nativeTokenData = JSON.parse(tokenData) as NativeTokenData;
277+
resolve(new AccessTokenData(nativeTokenData));
278+
},
279+
error => reject(error)
280+
);
281+
});
282+
}
283+
266284
/**
267285
* This function does not return anything back on success.
268286
* @param {screenAction} The screen state that miniapp wants to set on device.

js-miniapp-bridge/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from './types/custom-permissions';
1717
import { ShareInfoType } from './types/share-info';
1818
import { ScreenOrientation } from './types/screen';
19+
import { AccessTokenData } from './types/token-data';
1920

2021
export {
2122
MiniAppBridge,
@@ -28,4 +29,5 @@ export {
2829
CustomPermissionResult,
2930
ShareInfoType,
3031
ScreenOrientation,
32+
AccessTokenData,
3133
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/** @internal */
2+
export interface NativeTokenData {
3+
token: string;
4+
validUntil: number;
5+
}
6+
7+
/** Token data type. */
8+
export class AccessTokenData {
9+
readonly token: string;
10+
readonly validUntil: Date;
11+
12+
constructor(baseToken: NativeTokenData) {
13+
this.token = baseToken.token;
14+
this.validUntil = new Date(baseToken.validUntil);
15+
}
16+
}

js-miniapp-sample/src/js_sdk/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,7 @@ export const isMobile = () => {
44
const parser = Bowser.getParser(window.navigator.userAgent);
55
return parser.getPlatform().type === 'mobile';
66
};
7+
8+
export const displayDate = (date: Date) => {
9+
return date.toLocaleDateString(`ja-JP`);
10+
};

js-miniapp-sample/src/pages/auth-token.js

Lines changed: 17 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
import React, { useReducer, useState } from 'react';
1+
import React, { useReducer } from 'react';
2+
import MiniApp from 'js-miniapp-sdk';
3+
import { displayDate } from '../js_sdk';
24

35
import {
46
Button,
5-
Switch,
67
CircularProgress,
78
FormGroup,
8-
Grid,
99
Typography,
1010
CardContent,
1111
} from '@material-ui/core';
1212
import { red, green } from '@material-ui/core/colors';
1313
import { makeStyles } from '@material-ui/core/styles';
14-
import axios from 'axios';
1514
import clsx from 'clsx';
1615

1716
import GreyCard from '../components/GreyCard';
@@ -73,13 +72,14 @@ const dataFetchReducer = (state, action) => {
7372
...state,
7473
isLoading: false,
7574
isError: false,
76-
response: action.payload,
75+
response: action.tokenData,
7776
};
7877
case 'FETCH_FAILURE':
7978
return {
8079
...state,
8180
isLoading: false,
8281
isError: true,
82+
errorMessage: action.errorMessage,
8383
};
8484
default:
8585
throw new Error();
@@ -95,20 +95,15 @@ function AuthToken() {
9595
[classes.buttonSuccess]: state.response,
9696
});
9797

98-
const [switchState, setSwitchState] = useState(true);
99-
10098
function requestToken() {
101-
// Hardcoded API values to test
102-
const API = switchState
103-
? 'http://www.mocky.io/v2/5e9406873100006c005e2d00'
104-
: 'http://www.mocky.io/v2/5e9806e43500006a00c47d6f';
105-
axios
106-
.get(API)
99+
MiniApp.user
100+
.getAccessToken()
107101
.then((response) => {
108-
dispatch({ type: 'FETCH_SUCCESS', payload: response.data });
102+
dispatch({ type: 'FETCH_SUCCESS', tokenData: response });
109103
})
110104
.catch((error) => {
111-
dispatch({ type: 'FETCH_FAILURE' });
105+
console.error(error);
106+
dispatch({ type: 'FETCH_FAILURE', errorMessage: error });
112107
});
113108
}
114109

@@ -120,26 +115,6 @@ function AuthToken() {
120115
}
121116
}
122117

123-
function SwitchToggle() {
124-
return (
125-
<Typography component="div">
126-
<Grid component="label" container alignItems="center" spacing={1}>
127-
<Grid item>Success</Grid>
128-
<Grid item>
129-
<Switch
130-
color="primary"
131-
checked={switchState}
132-
onChange={() => setSwitchState(!switchState)}
133-
name="switchState"
134-
data-testid="authSwitch"
135-
/>
136-
</Grid>
137-
<Grid item>Failure</Grid>
138-
</Grid>
139-
</Typography>
140-
);
141-
}
142-
143118
function ButtonWrapper() {
144119
return (
145120
<div className={classes.wrapper}>
@@ -164,28 +139,20 @@ function AuthToken() {
164139
<GreyCard height="auto">
165140
<CardContent>
166141
<FormGroup column="true" classes={{ root: classes.rootFormGroup }}>
167-
<Typography variant="body2" align="center">
168-
Please note that we use a <strong>mocked API</strong> in this
169-
example (
170-
<a href="http://www.mocky.io/v2/5e9806e43500006a00c47d6f">
171-
Success
172-
</a>{' '}
173-
&{' '}
174-
<a href="http://www.mocky.io/v2/5e9406873100006c005e2d00">
175-
Failure
176-
</a>
177-
)
178-
</Typography>
179-
{SwitchToggle()}
180142
{ButtonWrapper()}
181143
{state.isError && (
182144
<Typography variant="body1" className={classes.error}>
183-
Error fetching the Token
145+
{state.errorMessage}
146+
</Typography>
147+
)}
148+
{state.response && (
149+
<Typography variant="body1" className={classes.success}>
150+
Token: {state.response.token}
184151
</Typography>
185152
)}
186153
{state.response && (
187154
<Typography variant="body1" className={classes.success}>
188-
{JSON.stringify(state.response.data)}
155+
Valid until: {displayDate(state.response.validUntil)}
189156
</Typography>
190157
)}
191158
</FormGroup>

js-miniapp-sample/src/pages/tests/auth-token.test.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,3 @@ test('Button is rendered', () => {
1515
const button = screen.getByTestId('authButton');
1616
expect(button).toBeInTheDocument();
1717
});
18-
19-
test('Switch is rendered', () => {
20-
const authSwitch = screen.getByTestId('authSwitch');
21-
expect(authSwitch).toBeInTheDocument();
22-
});

js-miniapp-sample/src/pages/tests/fetch-credentials.test.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,6 @@ test('Button is rendered', () => {
1414
expect(button).toBeInTheDocument();
1515
});
1616

17-
test('Switch is rendered', () => {
18-
const { getByTestId } = render(wrapTheme(<AuthToken />));
19-
const authSwitch = getByTestId('authSwitch');
20-
expect(authSwitch).toBeInTheDocument();
21-
});
22-
2317
describe('Test Reducer', () => {
2418
test('The init action updates state properly', () => {
2519
expect(initialState.isLoading).toBe(false);

js-miniapp-sdk/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
CustomPermissionResult,
1313
ShareInfoType,
1414
ScreenOrientation,
15+
AccessTokenData,
1516
} from '../../js-miniapp-bridge/src';
1617

1718
import { MiniApp } from './miniapp';
@@ -28,4 +29,5 @@ export {
2829
Reward,
2930
ShareInfoType,
3031
ScreenOrientation,
32+
AccessTokenData,
3133
};

js-miniapp-sdk/src/miniapp.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
CustomPermissionResult,
77
ShareInfoType,
88
ScreenOrientation,
9+
AccessTokenData,
910
} from '../../js-miniapp-bridge/src';
1011

1112
/**
@@ -91,18 +92,23 @@ interface Platform {
9192
}
9293

9394
/**
94-
* Interfaces to retrieve User profile related information
95+
* Interfaces to retrieve User profile related information.
9596
*/
9697
export interface UserInfoProvider {
9798
/**
98-
* @returns Username saved in the host app user profile
99+
* @returns Username saved in the host app user profile.
99100
*/
100101
getUserName(): Promise<string>;
101102

102103
/**
103-
* @returns Profile photo saved in the host app user profile
104+
* @returns Profile photo saved in the host app user profile.
104105
*/
105106
getProfilePhoto(): Promise<string>;
107+
108+
/**
109+
* @returns Access token from native hostapp.
110+
*/
111+
getAccessToken(): Promise<AccessTokenData>;
106112
}
107113

108114
/** @internal */
@@ -120,6 +126,10 @@ class UserInfo implements UserInfoProvider {
120126
getProfilePhoto(): Promise<string> {
121127
return this.bridge.getProfilePhoto();
122128
}
129+
130+
getAccessToken(): Promise<AccessTokenData> {
131+
return this.bridge.getAccessToken();
132+
}
123133
}
124134

125135
/* tslint:disable:no-any */

js-miniapp-sdk/test/miniapp.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
CustomPermissionName,
99
CustomPermissionStatus,
1010
ScreenOrientation,
11+
AccessTokenData,
1112
} from '../../js-miniapp-bridge/src';
1213
import { MiniApp } from '../src/miniapp';
1314

@@ -26,6 +27,7 @@ window.MiniAppBridge = {
2627
getPlatform: sinon.stub(),
2728
getUserName: sinon.stub(),
2829
getProfilePhoto: sinon.stub(),
30+
getAccessToken: sinon.stub(),
2931
setScreenOrientation: sinon.stub(),
3032
};
3133
const miniApp = new MiniApp();
@@ -226,6 +228,18 @@ describe('getProfilePhoto', () => {
226228
});
227229
});
228230

231+
describe('getAccessToken', () => {
232+
it('should retrieve AccessTokenData from the MiniAppBridge when request is successful', () => {
233+
const response = {
234+
token: 'test_token',
235+
validUntil: 0,
236+
};
237+
238+
window.MiniAppBridge.getAccessToken.resolves(response);
239+
return expect(miniApp.user.getAccessToken()).to.eventually.equal(response);
240+
});
241+
});
242+
229243
describe('requestScreenOrientation', () => {
230244
it('should retrieve success from the MiniAppBridge when request is successful', () => {
231245
const response = 'success';

0 commit comments

Comments
 (0)