11import sidebarApps from "sidebarApps" ;
2+ import DOMPurify from "dompurify" ;
23
34// Singleton instance
45let instance = null ;
@@ -107,21 +108,24 @@ export default class NotificationManager {
107108 data-id = { notification . id }
108109 > </ div >
109110 ) ;
111+ const safeIcon = this . sanitizeIcon ( this . parseIcon ( notification . icon ) ) ;
112+ const safeTitle = this . sanitizeText ( notification . title ) ;
113+ const safeMessage = this . sanitizeText ( notification . message ) ;
110114 element . innerHTML = `
111- <div class="notification-icon">
112- ${ this . parseIcon ( notification . icon ) }
113- </div>
114- <div class="notification-content">
115- <div class="notification-title">
116- ${ notification . title }
117- <span class="notification-time">${ this . formatTime ( notification . time ) } </span>
115+ <div class="notification-icon">
116+ ${ safeIcon }
118117 </div>
119- <div class="notification-message">${ notification . message } </div>
120- <div class="notification-actions">
121- <div class="action-button">Dismiss</div>
118+ <div class="notification-content">
119+ <div class="notification-title">
120+ ${ safeTitle }
121+ <span class="notification-time">${ this . formatTime ( notification . time ) } </span>
122+ </div>
123+ <div class="notification-message">${ safeMessage } </div>
124+ <div class="notification-actions">
125+ <div class="action-button">Dismiss</div>
126+ </div>
122127 </div>
123- </div>
124- ` ;
128+ ` ;
125129 if ( notification . action ) {
126130 element . addEventListener ( "click" , ( e ) => {
127131 if ( e . target . closest ( ".action-button" ) ) {
@@ -140,16 +144,27 @@ export default class NotificationManager {
140144 data-id = { notification . id }
141145 > </ div >
142146 ) ;
147+ const safeIcon = this . sanitizeIcon ( this . parseIcon ( notification . icon ) ) ;
148+ const safeTitle = this . sanitizeText ( notification . title ) ;
149+ const safeMessage = this . sanitizeText ( notification . message ) ;
143150 element . innerHTML = `
144- <div class="notification-icon">${ this . parseIcon ( notification . icon ) } </div>
145- <div class="notification-content">
146- <div class="notification-title">
147- ${ notification . title }
151+ <div class="notification-icon">${ safeIcon } </div>
152+ <div class="notification-content">
153+ <div class="notification-title">
154+ ${ safeTitle }
155+ </div>
156+ <div class="notification-message">${ safeMessage } </div>
148157 </div>
149- <div class="notification-message">${ notification . message } </div>
150- </div>
151- ${ notification . autoClose ? "" : `<span class="close-icon icon clearclose" onclick="event.stopPropagation(); this.closest('.notification-toast').remove();"></span>` }
152- ` ;
158+ ${ notification . autoClose ? "" : `<span class="close-icon icon clearclose"></span>` }
159+ ` ;
160+
161+ const closeIcon = element . querySelector ( ".close-icon" ) ;
162+ if ( closeIcon ) {
163+ closeIcon . addEventListener ( "click" , ( event ) => {
164+ event . stopPropagation ( ) ;
165+ element . remove ( ) ;
166+ } ) ;
167+ }
153168 if ( notification . action ) {
154169 element . addEventListener ( "click" , ( ) =>
155170 notification . action ( notification ) ,
@@ -202,13 +217,27 @@ export default class NotificationManager {
202217 }
203218
204219 parseIcon ( icon ) {
205- if ( ! icon ) return this . DEFAULT_ICON ;
220+ if ( typeof icon !== "string" || ! icon ) return this . DEFAULT_ICON ;
206221 if ( icon . startsWith ( "<svg" ) ) return icon ;
207222 if ( icon . startsWith ( "data:" ) || icon . startsWith ( "http" ) )
208223 return `<img src="${ icon } " alt="notification" width="16" height="16">` ;
209224 return `<i class="icon ${ icon } "></i>` ;
210225 }
211226
227+ sanitizeText ( text ) {
228+ return DOMPurify . sanitize ( String ( text ?? "" ) , {
229+ ALLOWED_TAGS : [ ] ,
230+ ALLOWED_ATTR : [ ] ,
231+ } ) ;
232+ }
233+
234+ sanitizeIcon ( iconMarkup ) {
235+ return DOMPurify . sanitize ( iconMarkup , {
236+ USE_PROFILES : { html : true , svg : true } ,
237+ ALLOW_DATA_ATTR : false ,
238+ } ) ;
239+ }
240+
212241 formatTime ( date ) {
213242 const now = new Date ( ) ;
214243 const diff = Math . floor ( ( now - date ) / 1000 ) ;
0 commit comments