@@ -149,6 +149,112 @@ async function getActiveUserBlocking() {
149149 }
150150}
151151
152+ class RefreshIdpTokenResult {
153+ idpConfigId ;
154+ idToken ;
155+ }
156+
157+ class TokenRefreshHandlerImpl {
158+ /**
159+ * Opens a popup to get a 3P ID token and Config ID from the user.
160+ * @returns {Promise<RefreshIdpTokenResult> } A promise that resolves with the result object.
161+ */
162+ refreshIdpToken ( ) {
163+ log ( 'inside here' ) ;
164+ console . log ( 'inside handler - opening popup for 3p token' ) ;
165+
166+ // This function handles the popup logic and returns the required object
167+ return this . promptForTokenAndConfigId ( ) ;
168+ }
169+
170+ /**
171+ * Opens a Bootstrap modal to ask the user for an ID token and IDP Config ID.
172+ *
173+ * This function dynamically creates a modal, shows it, and waits for
174+ * user input. It returns a Promise that resolves or rejects based
175+ * on the user's action.
176+ *
177+ * @returns {Promise<RefreshIdpTokenResult> } A promise that resolves with the
178+ * RefreshIdpTokenResult object, or rejects if the user cancels.
179+ */
180+ promptForTokenAndConfigId ( ) {
181+ // We return a Promise that will be resolved/rejected by the modal's buttons
182+ return new Promise ( ( resolve , reject ) => {
183+ // A flag to track if the promise has been settled
184+ let isSubmitted = false ;
185+ const modalId = 'third-party-token-modal' ;
186+
187+ // 1. Define Modal HTML with two input fields
188+ const modalHtml = `
189+ <div class="modal fade" id="${ modalId } " tabindex="-1" role="dialog" aria-labelledby="tokenModalLabel">
190+ <div class="modal-dialog" role="document">
191+ <div class="modal-content">
192+ <div class="modal-header">
193+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
194+ <span aria-hidden="true">×</span>
195+ </button>
196+ <h4 class="modal-title" id="tokenModalLabel">Enter 3P Token Details</h4>
197+ </div>
198+ <div class="modal-body">
199+ <p>Please enter the third-party token details:</p>
200+ <div class="form-group">
201+ <label for="idp-config-id-input-field">IDP Config ID</label>
202+ <input type="text" class="form-control" id="idp-config-id-input-field" placeholder="eg: idp.example.com">
203+ </div>
204+ <div class="form-group">
205+ <label for="id-token-input-field">ID Token</label>
206+ <input type="text" class="form-control" id="id-token-input-field" placeholder="Paste ID Token here">
207+ </div>
208+ </div>
209+ <div class="modal-footer">
210+ <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
211+ <button type="button" class="btn btn-primary" id="token-submit-btn">Submit</button>
212+ </div>
213+ </div>
214+ </div>
215+ </div>
216+ ` ;
217+
218+ // 2. Append modal to body and get a jQuery reference
219+ $ ( 'body' ) . append ( modalHtml ) ;
220+ const $modal = $ ( `#${ modalId } ` ) ;
221+
222+ // 3. Setup Event Handlers
223+
224+ // Handle Submit button click
225+ $modal . find ( '#token-submit-btn' ) . on ( 'click' , ( ) => {
226+ isSubmitted = true ;
227+
228+ // Read values from *both* input fields
229+ const configId = $modal . find ( '#idp-config-id-input-field' ) . val ( ) ;
230+ const token = $modal . find ( '#id-token-input-field' ) . val ( ) ;
231+
232+ $modal . modal ( 'hide' ) ; // Hide the modal
233+
234+ // Create the result object as requested
235+ const result = new RefreshIdpTokenResult ( ) ;
236+ result . idpConfigId = configId ;
237+ result . idToken = token ;
238+
239+ resolve ( result ) ; // Resolve the promise with the object
240+ } ) ;
241+
242+ // Handle modal being closed (by 'x', 'Cancel' button, backdrop click, or ESC)
243+ $modal . on ( 'hidden.bs.modal' , ( ) => {
244+ $modal . remove ( ) ; // Clean up the modal from the DOM
245+
246+ // If the modal was hidden *without* submitting, reject the promise
247+ if ( ! isSubmitted ) {
248+ reject ( new Error ( 'User cancelled token input.' ) ) ;
249+ }
250+ } ) ;
251+
252+ // 4. Show the modal
253+ $modal . modal ( 'show' ) ;
254+ } ) ;
255+ }
256+ }
257+
152258/**
153259 * Refreshes the current user data in the UI, displaying a user info box if
154260 * a user is signed in, or removing it.
@@ -2092,6 +2198,8 @@ function initApp() {
20922198 popupRedirectResolver : browserPopupRedirectResolver ,
20932199 tenantConfig : tenantConfig
20942200 } ) ;
2201+ const tokenRefreshHandler = new TokenRefreshHandlerImpl ( ) ;
2202+ regionalAuth . setTokenRefreshHandler ( tokenRefreshHandler ) ;
20952203
20962204 const firebaseTokenStatus = document . getElementById ( 'firebase-token-status' ) ;
20972205 setTimeout ( async ( ) => {
0 commit comments