From 18d5b6dd9abce9f4104a7e1453fcd7cb64067245 Mon Sep 17 00:00:00 2001 From: mario Date: Tue, 13 May 2025 16:15:37 +0700 Subject: [PATCH] add: shortlink DoB auth page --- platform/app/public/config/google.js | 6 +- platform/app/src/routes/ShortlinkLogin.tsx | 131 ++++++++++++++++++ platform/app/src/routes/index.tsx | 5 + .../utils/initUserAuthenticationService.js | 12 ++ 4 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 platform/app/src/routes/ShortlinkLogin.tsx diff --git a/platform/app/public/config/google.js b/platform/app/public/config/google.js index 5b1d75f..d9cabc0 100644 --- a/platform/app/public/config/google.js +++ b/platform/app/public/config/google.js @@ -3,7 +3,7 @@ window.config = { routerBasename: '/', pacs_document_host: '152.42.173.210', pacs_document_port: 8080, - expertise:false, + expertise: false, enableGoogleCloudAdapter: false, // below flag is for performance reasons, but it might not work for all servers showWarningMessageForCrossOrigin: true, @@ -48,9 +48,9 @@ window.config = { imageRendering: 'wadors', thumbnailRendering: 'wadors', enableStudyLazyLoad: true, - supportsFuzzyMatching: true, + supportsFuzzyMatching: false, supportsWildcard: true, - dicomUploadEnabled: true, + dicomUploadEnabled: false, omitQuotationForMultipartRequest: true, configurationAPI: 'ohif.dataSourceConfigurationAPI.google', // defaultDicomStoreConfiguredItems: { diff --git a/platform/app/src/routes/ShortlinkLogin.tsx b/platform/app/src/routes/ShortlinkLogin.tsx new file mode 100644 index 0000000..b4339ac --- /dev/null +++ b/platform/app/src/routes/ShortlinkLogin.tsx @@ -0,0 +1,131 @@ +import React, { useState, useEffect } from 'react'; +import { useNavigate, useLocation } from 'react-router-dom'; +import { useUserAuthentication } from '@ohif/ui'; + +const ShortlinkLogin = () => { + const [dob, setDob] = useState(''); + const [shortToken, setShortToken] = useState(''); + const [error, setError] = useState(''); + const [isLoading, setIsLoading] = useState(false); + const navigate = useNavigate(); + const location = useLocation(); + const [, authContext] = useUserAuthentication(); + + // Parse the short token from URL query params + useEffect(() => { + const searchParams = new URLSearchParams(location.search); + const token = searchParams.get('short'); + + if (token) { + setShortToken(token); + } else { + // No short token found, redirect to regular login + setError('No shortlink token found in URL'); + setTimeout(() => { + navigate('/login', { replace: true }); + }, 3000); + } + }, [location.search, navigate]); + + // Handle form submission + const handleSubmit = async e => { + e.preventDefault(); + setError(''); + setIsLoading(true); + + try { + // Use window.config.goProxyHost for authentication endpoint + const proxyHost = window.config?.goProxyHost || `http://${window.location.hostname}:5555`; + const authEndpoint = `${proxyHost}/auth/shortlink`; + + // Call the shortlink authentication endpoint + const response = await fetch(authEndpoint, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ short_token: shortToken, dob }), + }); + + if (!response.ok) { + throw new Error('Authentication failed. Please check your date of birth and try again.'); + } + + const data = await response.json(); + + // Store token in sessionStorage + window.sessionStorage.setItem('ohif-auth-token', data.access_token); + + // Decode token to extract user information (if available in token) + let userInfo = data.user; + + // Update the auth context + authContext.setUser({ + ...userInfo, + token: data.access_token, + }); + + // Set window.config.sasGetToken for the injectAuth function + if (window.config) { + window.config.sasGetToken = () => window.sessionStorage.getItem('ohif-auth-token'); + } + + // Navigate to the viewer page with the authenticated patient's study + // The actual URL would depend on how studies are loaded in your OHIF instance + if (data.redirect_url) { + navigate(data.redirect_url, { replace: true }); + } else { + // Default navigation if no specific redirect is provided + navigate('/', { replace: true }); + } + } catch (error) { + console.error('Authentication error:', error); + setError(error.message || 'Failed to authenticate. Please try again.'); + } finally { + setIsLoading(false); + } + }; + + const handleDateChange = e => { + // Format date input as YYYY-MM-DD + setDob(e.target.value); + }; + + return ( +
+
+

Patient Access

+ + {error &&
{error}
} + +
+
+ + +

Format: Bulan - Tanggal - Tahun

+
+ +
+ +
+
+
+
+ ); +}; + +export default ShortlinkLogin; diff --git a/platform/app/src/routes/index.tsx b/platform/app/src/routes/index.tsx index 8c5ef8d..39d171e 100644 --- a/platform/app/src/routes/index.tsx +++ b/platform/app/src/routes/index.tsx @@ -13,6 +13,7 @@ import PrivateRoute from './PrivateRoute'; import PropTypes from 'prop-types'; import { Link } from 'react-router-dom'; import Login from './Login'; +import ShortlinkLogin from './ShortlinkLogin'; const NotFoundServer = ({ message = 'Unable to query for studies at this time. Check your data source configuration or network connection', @@ -80,6 +81,10 @@ const bakedInRoutes = [ path: '/login', children: Login, }, + { + path: '/short-auth', + children: ShortlinkLogin, + }, ]; // NOT FOUND (404) diff --git a/platform/app/src/utils/initUserAuthenticationService.js b/platform/app/src/utils/initUserAuthenticationService.js index 4b1d7fe..a527066 100644 --- a/platform/app/src/utils/initUserAuthenticationService.js +++ b/platform/app/src/utils/initUserAuthenticationService.js @@ -7,6 +7,17 @@ export function initializeCustomAuth(userAuthenticationService) { userAuthenticationService.setServiceImplementation({ // Custom implementation to handle unauthenticated users handleUnauthenticated: () => { + // Check if there's a shortlink token in the URL + const urlParams = new URLSearchParams(window.location.search); + const shortToken = urlParams.get('short'); + + // If there's a shortlink token, redirect to the shortlink login page + if (shortToken) { + window.location.href = `/short-auth?short=${shortToken}`; + return null; + } + + // Otherwise, handle as normal login flow // Get the current path for redirect after login const currentPath = window.location.pathname + window.location.search; @@ -21,6 +32,7 @@ export function initializeCustomAuth(userAuthenticationService) { }, // Custom implementation to get the authorization header + // di ohif3.9.1 ini sepertinya masih development // getAuthorizationHeader: () => { // const token = window.sessionStorage.getItem('ohif-auth-token'); // return token ? `Bearer ${token}` : undefined;