1212</ head >
1313
1414< body class ="loading-page ">
15- < h2 > Completing signing…</ h2 >
16- < div class ="spinner "> </ div >
17-
15+ < div id ="spinner-message ">
16+ < h2 > Completing signing…</ h2 >
17+ < div class ="spinner "> </ div >
18+ </ div >
1819< div id ="error-message " class ="alert alert-danger " style ="display: none; " role ="alert ">
1920 < div class ="message "> </ div >
2021 < pre class ="details "> </ pre >
@@ -25,85 +26,78 @@ <h2>Completing signing…</h2>
2526</ p >
2627
2728< script type ="module ">
28- import { showErrorMessage } from '/js/errors.js' ;
29+ import { showErrorMessage , checkHttpError } from '/js/errors.js' ;
2930
31+ // Using an async IIFE for mobile WebView compatibility:
32+ // top-level await is not supported in some mobile browsers/WebViews.
3033 ( async ( ) => {
31- try {
32- const fragment = window . location . hash . slice ( 1 ) ;
33-
34- if ( ! fragment ) {
35- throw new Error ( "Missing payload fragment" ) ;
36- }
37-
38- const decoded = atob ( fragment ) ;
39- const payload = JSON . parse ( decoded ) ;
40-
41- if ( payload . error ) {
42- console . error ( "WebEID mobile error:" , payload ) ;
43-
44- showErrorMessage ( {
45- code : payload . code ?? "UNKNOWN_ERROR" ,
46- message : payload . message ?? "Signing failed" ,
47- } ) ;
48-
49- const actions = document . getElementById ( "error-actions" ) ;
50- const goBackButton = document . getElementById ( "back-button" ) ;
51- actions . style . display = "block" ;
52- goBackButton . addEventListener ( "click" , ( ) => {
53- window . location . replace ( "/welcome?error=webeid-callback" ) ;
54- } ) ;
55-
56- return ;
57- }
58-
59- const csrfHeaderName = document . querySelector ( '#csrfheadername' ) . content ;
60- const csrfToken = document . querySelector ( '#csrftoken' ) . content ;
61- const path = window . location . pathname ;
34+ const fragment = window . location . hash . slice ( 1 ) ;
6235
63- let endpoint ;
64- if ( path . includes ( "/sign/mobile/certificate" ) ) {
65- endpoint = "/sign/mobile/certificate" ;
66-
67- payload . certificate = payload . certificate || payload . signingCertificate || null ;
68- payload . supportedSignatureAlgorithms = payload . supportedSignatureAlgorithms || [ ] ;
69-
70- } else if ( path . includes ( "/sign/mobile/signature" ) ) {
71- endpoint = "/sign/mobile/signature" ;
72- } else {
73- throw new Error ( "Unexpected callback path: " + path ) ;
74- }
75-
76- const response = await fetch ( endpoint , {
77- method : "POST" ,
78- headers : {
79- "Content-Type" : "application/json" ,
80- [ csrfHeaderName ] : csrfToken ,
81- } ,
82- credentials : "include" ,
83- body : JSON . stringify ( payload ) ,
84- } ) ;
36+ if ( ! fragment ) {
37+ throw new Error ( "Missing response payload" ) ;
38+ }
8539
86- if ( ! response . ok ) {
87- throw new Error ( await response . text ( ) ) ;
88- }
40+ let payload ;
41+ try {
42+ payload = JSON . parse ( atob ( fragment ) ) ;
43+ } catch ( e ) {
44+ console . error ( e )
45+ throw new Error ( "Failed to parse the response" ) ;
46+ }
8947
90- const result = await response . json ( ) ;
48+ if ( payload . error ) {
49+ const error = new Error ( payload . message ?? "Signing failed" ) ;
50+ error . code = payload . code ;
51+ throw error ;
52+ }
9153
92- if ( endpoint . endsWith ( "/certificate" ) ) {
93- const { request_uri } = result ;
94- window . location . replace ( request_uri ) ;
95- return ;
96- }
54+ const path = window . location . pathname ;
55+ let endpoint ;
56+ if ( path === "/sign/mobile/certificate" ) {
57+ endpoint = "/sign/mobile/certificate" ;
58+ } else if ( path === "/sign/mobile/signature" ) {
59+ endpoint = "/sign/mobile/signature" ;
60+ } else {
61+ const error = new Error ( "Unexpected callback path: " + path ) ;
62+ error . code = "INVALID_CALLBACK_PATH" ;
63+ throw error ;
64+ }
9765
98- window . location . replace (
99- "/welcome?signed=" + encodeURIComponent ( result . name )
100- ) ;
66+ const csrfHeaderName = document . querySelector ( '#csrfheadername' ) . content ;
67+ const csrfToken = document . querySelector ( '#csrftoken' ) . content ;
68+ const response = await fetch ( endpoint , {
69+ method : "POST" ,
70+ headers : {
71+ "Content-Type" : "application/json" ,
72+ [ csrfHeaderName ] : csrfToken ,
73+ } ,
74+ credentials : "include" ,
75+ body : JSON . stringify ( payload ) ,
76+ } ) ;
77+ await checkHttpError ( response ) ;
78+
79+ const result = await response . json ( ) ;
80+ if ( endpoint . endsWith ( "/certificate" ) ) {
81+ const { request_uri} = result ;
82+ window . location . replace ( request_uri ) ;
83+ return ;
84+ }
10185
102- } catch ( error ) {
103- console . error ( "Mobile callback failed" , error ) ;
86+ window . location . replace (
87+ "/welcome?signed=" + encodeURIComponent ( result . name )
88+ ) ;
89+ } ) ( ) . catch ( ( error ) => {
90+ console . error ( error ) ;
91+ showErrorMessage ( error , "Signing failed" ) ;
92+ const spinner = document . querySelector ( "#spinner-message" )
93+ spinner . style . display = "none" ;
94+ const actions = document . getElementById ( "error-actions" ) ;
95+ const goBackButton = document . getElementById ( "back-button" ) ;
96+ actions . style . display = "block" ;
97+ goBackButton . addEventListener ( "click" , ( ) => {
10498 window . location . replace ( "/welcome?error=webeid-callback" ) ;
105- }
106- } ) ( ) ;
99+ } ) ;
100+ } ) ;
107101</ script >
108102</ body >
109103</ html >
0 commit comments