@@ -3,22 +3,114 @@ type ApplicationConfig = {
33 redirectUri : string ,
44 clientApplicationId : string ,
55 idpBaseUrl : string
6+ apiBaseUrl : string
67 authenticationCheckInterval : number
78
89}
10+
11+ type ConfigManagerResponse = {
12+ redirectUri : string ,
13+ clientApplicationId : string ,
14+ idpBaseUrl : string
15+ apiBaseUrl : string
16+ authenticationCheckInterval : string | number
17+ }
18+
19+ const appConfigStorageKey = "appConfig"
20+ const defaultScope = "openid email profile"
21+ const configManagerEndpoint = "/api/config"
22+ let applicationConfigRequest : Promise < ApplicationConfig > | null = null
23+
24+ const isLogoutRequest = ( ) => {
25+ const pathname = window . location . pathname
26+ return pathname . endsWith ( "/logout" ) || pathname . endsWith ( "/logout.html" )
27+ }
28+
29+ const toApplicationConfig = ( configData : ConfigManagerResponse ) : ApplicationConfig => ( {
30+ scope : defaultScope ,
31+ redirectUri : configData . redirectUri ,
32+ clientApplicationId : configData . clientApplicationId ,
33+ idpBaseUrl : configData . idpBaseUrl ,
34+ apiBaseUrl : configData . apiBaseUrl ,
35+ authenticationCheckInterval : Number ( configData . authenticationCheckInterval ) ,
36+ } )
37+
38+ const loadApplicationConfigFromCache = ( ) : ApplicationConfig | null => {
39+ const cachedConfig = window . sessionStorage . getItem ( appConfigStorageKey )
40+
41+ if ( ! cachedConfig ) {
42+ return null
43+ }
44+
45+ try {
46+ return toApplicationConfig ( JSON . parse ( cachedConfig ) as ConfigManagerResponse )
47+ } catch ( e ) {
48+ window . sessionStorage . removeItem ( appConfigStorageKey )
49+ return null
50+ }
51+ }
52+
53+ const loadApplicationConfigFromConfigManager = async ( ) : Promise < ApplicationConfig > => {
54+ const response = await fetch ( configManagerEndpoint , {
55+ method : "GET" ,
56+ headers : {
57+ "Accept" : "application/json" ,
58+ } ,
59+ mode : "cors" ,
60+ } )
61+
62+ if ( ! response . ok ) {
63+ throw new Error ( `Unable to load application configuration: ${ response . status } ` )
64+ }
65+
66+ return toApplicationConfig ( await response . json ( ) as ConfigManagerResponse )
67+ }
68+
69+ const cacheApplicationConfig = ( configData : ApplicationConfig ) => {
70+ window . sessionStorage . setItem ( appConfigStorageKey , JSON . stringify ( configData ) )
71+ }
72+
73+ export const clearApplicationConfigCache = ( ) => {
74+ window . sessionStorage . removeItem ( appConfigStorageKey )
75+ applicationConfigRequest = null
76+ }
77+
978export const applicationConfigLoader = async ( ) => {
10- const configData = {
11- scope : "openid email profile" ,
12- redirectUri : process . env . REDIRECT_URI ,
13- clientApplicationId : process . env . CLIENT_APPLICATION_ID ,
14- idpBaseUrl : process . env . IDP_BASE_URL ,
15- authenticationCheckInterval : Number ( process . env . AUTHENTICATION_CHECK_INTERVAL ) ,
79+ const logoutRequest = isLogoutRequest ( )
80+ const cachedConfig = loadApplicationConfigFromCache ( )
1681
17- } ;
18- return configData as ApplicationConfig
82+ if ( cachedConfig ) {
83+ if ( logoutRequest ) {
84+ clearApplicationConfigCache ( )
85+ }
86+ return cachedConfig
87+ }
88+
89+ if ( ! applicationConfigRequest ) {
90+ applicationConfigRequest = loadApplicationConfigFromConfigManager ( )
91+ . catch ( ( e ) => {
92+ applicationConfigRequest = null
93+ throw e
94+ } )
95+ }
96+
97+ const configData = await applicationConfigRequest
98+
99+ if ( ! logoutRequest ) {
100+ cacheApplicationConfig ( configData )
101+ } else {
102+ clearApplicationConfigCache ( )
103+ }
104+
105+ return configData
19106}
20107
21108export async function getIdpBaseUrl ( ) {
22109 const appConfig = await applicationConfigLoader ( )
23110 return appConfig . idpBaseUrl ;
24111}
112+
113+ export async function getApiBaseUrl ( ) {
114+ const appConfig = await applicationConfigLoader ( )
115+ return appConfig . apiBaseUrl ;
116+ }
0 commit comments