diff --git a/Sample-01/api-server.js b/Sample-01/api-server.js index 4e946daa..42db266d 100644 --- a/Sample-01/api-server.js +++ b/Sample-01/api-server.js @@ -2,7 +2,12 @@ const express = require("express"); const cors = require("cors"); const morgan = require("morgan"); const helmet = require("helmet"); -const { auth } = require("express-oauth2-jwt-bearer"); +const { + auth, + InvalidTokenError, + InvalidRequestError, + InsufficientScopeError +} = require("express-oauth2-jwt-bearer"); const authConfig = require("./src/auth_config.json"); const app = express(); @@ -11,11 +16,7 @@ const port = process.env.API_PORT || 3001; const appPort = process.env.SERVER_PORT || 3000; const appOrigin = authConfig.appOrigin || `http://localhost:${appPort}`; -if ( - !authConfig.domain || - !authConfig.audience || - authConfig.audience === "YOUR_API_IDENTIFIER" -) { +if (!authConfig.domain || !authConfig.audience || authConfig.audience === "YOUR_API_IDENTIFIER") { console.log( "Exiting: Please make sure that auth_config.json is in place and populated with valid domain and audience values" ); @@ -27,16 +28,35 @@ app.use(morgan("dev")); app.use(helmet()); app.use(cors({ origin: appOrigin })); -const checkJwt = auth({ - audience: authConfig.audience, - issuerBaseURL: `https://${authConfig.domain}/`, - algorithms: ["RS256"], -}); +app.use( + auth({ + audience: authConfig.audience, + issuerBaseURL: `https://${authConfig.domain}/`, + algorithms: ["RS256"], + }) +); -app.get("/api/external", checkJwt, (req, res) => { +app.get("/api/external", (req, res) => { res.send({ msg: "Your access token was successfully validated!", }); }); +// Custom error handler that will turn the errors from express-oauth2-jwt-bearer into a JSON object +// for the UI to handle +app.use((err, req, res, next) => { + if ( + err instanceof InvalidTokenError || + err instanceof InvalidRequestError || + err instanceof InsufficientScopeError + ) { + return res.status(err.status).send({ + error: err.code, + message: err.message, + }); + } + + res.send(err); +}); + app.listen(port, () => console.log(`API Server listening on port ${port}`)); diff --git a/Sample-01/src/components/Highlight.js b/Sample-01/src/components/Highlight.js index 7bdecf31..f8a17dc9 100644 --- a/Sample-01/src/components/Highlight.js +++ b/Sample-01/src/components/Highlight.js @@ -1,73 +1,23 @@ -import React, { Component } from "react"; -import PropTypes from "prop-types"; - -import hljs from "highlight.js"; -import "highlight.js/styles/monokai-sublime.css"; - -const registeredLanguages = {}; - -class Highlight extends Component { - constructor(props) { - super(props); - - this.state = { loaded: false }; - this.codeNode = React.createRef(); - } - - componentDidMount() { - const { language } = this.props; - - if (language && !registeredLanguages[language]) { - try { - const newLanguage = require(`highlight.js/lib/languages/${language}`); - hljs.registerLanguage(language, newLanguage); - registeredLanguages[language] = true; - - this.setState({ loaded: true }, this.highlight); - } catch (e) { - console.error(e); - throw Error(`Cannot register the language ${language}`); - } - } else { - this.setState({ loaded: true }); - } - } - - componentDidUpdate() { - this.highlight(); - } - - highlight = () => { - this.codeNode && - this.codeNode.current && - hljs.highlightBlock(this.codeNode.current); - }; - - render() { - const { language, children } = this.props; - const { loaded } = this.state; - - if (!loaded) { - return null; - } - - return ( -
-
- {children}
-
-
- );
- }
-}
-
-Highlight.propTypes = {
- children: PropTypes.node.isRequired,
- language: PropTypes.string,
-};
-
-Highlight.defaultProps = {
- language: "json",
+import React, { useEffect, useRef } from 'react';
+
+import hljs from 'highlight.js';
+import 'highlight.js/styles/monokai-sublime.css';
+
+const Highlight = (props) => {
+ const { text, language = 'json' } = props;
+
+ const codeNode = useRef(null);
+ useEffect(() => {
+ hljs.highlightElement(codeNode.current);
+ }, [text]);
+
+ return (
+
+
+ {text}
+
+
+ );
};
-export default Highlight;
+export default Highlight;
\ No newline at end of file
diff --git a/Sample-01/src/views/ExternalApi.js b/Sample-01/src/views/ExternalApi.js
index 4f3c1d51..882d7e28 100644
--- a/Sample-01/src/views/ExternalApi.js
+++ b/Sample-01/src/views/ExternalApi.js
@@ -10,8 +10,10 @@ export const ExternalApiComponent = () => {
const [state, setState] = useState({
showResult: false,
- apiMessage: "",
+ showApiError: false,
error: null,
+ apiMessage: "",
+ apiError: null,
});
const {
@@ -64,12 +66,27 @@ export const ExternalApiComponent = () => {
},
});
+ if (!response.ok) {
+ const apiError = response.headers.get('content-type')?.includes('application/json')
+ ? JSON.stringify(await response.json(), null, 2)
+ : await response.text();
+ setState({
+ ...state,
+ showApiError: true,
+ showResult: false,
+ apiError
+ });
+ return;
+ }
+
const responseData = await response.json();
setState({
...state,
showResult: true,
apiMessage: responseData,
+ apiError: null,
+ showApiError: false
});
} catch (error) {
setState({
@@ -185,9 +202,14 @@ export const ExternalApiComponent = () => {
{state.showResult && (