11'use client' ;
22
33import styles from './style.module.scss' ;
4- import { useEffect , useState } from 'react' ;
4+ import { useEffect , useRef , useState } from 'react' ;
55import { useAppTranslation } from '@/lib/i18n' ;
66import { usePageSettings } from '@/module/pageSettings' ;
77import { useConnectedUser } from '@/module/user' ;
@@ -52,24 +52,6 @@ async function decryptData(data: string, pemEncodedKey: string): Promise<string>
5252 return String . fromCodePoint ( ...new Uint8Array ( buffer ) ) ;
5353}
5454
55- async function downloadReport ( api : API , privateKey : string ) {
56- api . get < string > ( '/admin/report' , { isFile : true } ) . on ( 'success' , async ( xml ) => {
57- let xmlString = xml ;
58- const encrypted = xml . matchAll ( / (?< = < (?< tag > [ ^ < > ] + ?) > ) [ ^ < > ] { 100 , } (? = < \/ \k<tag > > ) / g) ;
59- for ( const data of encrypted ) {
60- const realWorldData = await decryptData ( data [ 0 ] , privateKey ) ;
61- xmlString = xmlString . replaceAll ( data [ 0 ] , realWorldData ) ;
62- }
63- const blob = new Blob ( [ xmlString ] , { type : 'application/xml' } ) ;
64- const url = URL . createObjectURL ( blob ) ;
65- const a = document . createElement ( 'a' ) ;
66- a . href = url ;
67- a . download = `buckutt-report-${ Date . now ( ) } .xml` ;
68- a . click ( ) ;
69- URL . revokeObjectURL ( url ) ;
70- } ) ;
71- }
72-
7355type ConfigurationStatus = {
7456 debtor_iban : boolean ;
7557 debtor_bic : boolean ;
@@ -96,7 +78,20 @@ export default function AdminPage() {
9678 debtor_iban : false ,
9779 debtor_name : false ,
9880 } ) ;
81+ const [ error , setError ] = useState ( '' ) ;
9982 const [ hasSettingsOpen , setSettingsOpen ] = useState ( false ) ;
83+ const downloadedData = useRef ( '' ) ;
84+ const [ downloadedDataLink , setDownloadedDataLink ] = useState ( '' ) ;
85+
86+ useEffect ( ( ) => {
87+ if ( ! downloadedData . current ) setDownloadedDataLink ( '' ) ;
88+ else {
89+ const blob = new Blob ( [ downloadedData . current ] , { type : 'application/xml' } ) ;
90+ const url = URL . createObjectURL ( blob ) ;
91+ setDownloadedDataLink ( url ) ;
92+ return ( ) => URL . revokeObjectURL ( url ) ;
93+ }
94+ } , [ downloadedData . current ] ) ;
10095
10196 useEffect ( ( ) => {
10297 api . get < ConfigurationStatus > ( '/admin/config' ) . on ( 'success' , ( data ) => {
@@ -127,6 +122,40 @@ export default function AdminPage() {
127122 } ) ;
128123 } ;
129124
125+ const parseReport = async ( xml : string , privateKey : string ) => {
126+ let xmlString = xml ;
127+ const encrypted = xml . matchAll ( / (?< = < (?< tag > [ ^ < > ] + ?) > ) [ ^ < > ] { 100 , } (? = < \/ \k<tag > > ) / g) ;
128+ try {
129+ for ( const data of encrypted ) {
130+ const realWorldData = await decryptData ( data [ 0 ] , privateKey ) ;
131+ xmlString = xmlString . replaceAll ( data [ 0 ] , realWorldData ) ;
132+ }
133+ } catch {
134+ downloadedData . current = xml ;
135+ setError ( t ( 'common:admin.error_decrypt' ) ) ;
136+ return ;
137+ }
138+ setError ( '' ) ;
139+ const blob = new Blob ( [ xmlString ] , { type : 'application/xml' } ) ;
140+ const url = URL . createObjectURL ( blob ) ;
141+ const a = document . createElement ( 'a' ) ;
142+ a . href = url ;
143+ a . download = `buckutt-report-${ Date . now ( ) } .xml` ;
144+ a . click ( ) ;
145+ URL . revokeObjectURL ( url ) ;
146+ } ;
147+
148+ const downloadReport = async ( api : API , privateKey : string ) => {
149+ if ( downloadedData . current ) parseReport ( downloadedData . current , privateKey ) ;
150+ else
151+ api
152+ . get < string > ( '/admin/report' , { isFile : true } )
153+ . on ( 'success' , ( xml ) => parseReport ( xml , privateKey ) )
154+ . on ( 'error' , ( { error } ) => {
155+ setError ( error ) ;
156+ } ) ;
157+ } ;
158+
130159 return (
131160 < AppModal >
132161 < div className = { styles . title } >
@@ -136,6 +165,21 @@ export default function AdminPage() {
136165 </ span > { ' ' }
137166 🐩
138167 </ div >
168+ { error ? (
169+ < div className = { styles . warn } >
170+ { error === t ( 'common:admin.error_decrypt' )
171+ ? [
172+ error . slice ( 0 , error . indexOf ( '.' ) + 2 ) ,
173+ < a href = { downloadedDataLink } download = { `buckutt-raw-${ Date . now ( ) } .xml` } key = "link" >
174+ { error . slice ( error . indexOf ( '.' ) + 2 , error . indexOf ( '.' , error . indexOf ( '.' ) + 1 ) ) }
175+ </ a > ,
176+ error . slice ( error . indexOf ( '.' , error . indexOf ( '.' ) + 1 ) ) ,
177+ ]
178+ : error }
179+ </ div >
180+ ) : (
181+ < > </ >
182+ ) }
139183 { hasLoaded ? (
140184 hasSettingsOpen ? (
141185 < div className = { styles . margin } >
0 commit comments