mirror of
https://github.com/php-flasher/php-flasher.git
synced 2026-03-31 15:07:47 +01:00
Merge pull request #196 from php-flasher/issue-193
Introduce escapeHtml Option for Secure HTML Escaping in PHPFlasher
This commit is contained in:
@@ -19,6 +19,7 @@ export default class FlasherPlugin extends AbstractPlugin {
|
|||||||
direction: 'top',
|
direction: 'top',
|
||||||
rtl: false,
|
rtl: false,
|
||||||
style: {} as Properties,
|
style: {} as Properties,
|
||||||
|
escapeHtml: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(theme: Theme) {
|
constructor(theme: Theme) {
|
||||||
@@ -31,11 +32,12 @@ export default class FlasherPlugin extends AbstractPlugin {
|
|||||||
const render = () =>
|
const render = () =>
|
||||||
envelopes.forEach((envelope) => {
|
envelopes.forEach((envelope) => {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
const typeTimeout = this.options.timeout ?? this.options.timeouts[envelope.type] ?? 5000;
|
const typeTimeout = this.options.timeout ?? this.options.timeouts[envelope.type] ?? 5000
|
||||||
const options = {
|
const options = {
|
||||||
...this.options,
|
...this.options,
|
||||||
...envelope.options,
|
...envelope.options,
|
||||||
timeout: envelope.options.timeout ?? typeTimeout,
|
timeout: envelope.options.timeout ?? typeTimeout,
|
||||||
|
escapeHtml: (envelope.options.escapeHtml ?? this.options.escapeHtml) as boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addToContainer(this.createContainer(options), envelope, options)
|
this.addToContainer(this.createContainer(options), envelope, options)
|
||||||
@@ -64,7 +66,12 @@ export default class FlasherPlugin extends AbstractPlugin {
|
|||||||
return container
|
return container
|
||||||
}
|
}
|
||||||
|
|
||||||
private addToContainer(container: HTMLDivElement, envelope: Envelope, options: { direction: string, timeout: number, fps: number, rtl: boolean }): void {
|
private addToContainer(container: HTMLDivElement, envelope: Envelope, options: { direction: string, timeout: number, fps: number, rtl: boolean, escapeHtml: boolean }): void {
|
||||||
|
if (options.escapeHtml) {
|
||||||
|
envelope.title = this.escapeHtml(envelope.title)
|
||||||
|
envelope.message = this.escapeHtml(envelope.message)
|
||||||
|
}
|
||||||
|
|
||||||
const notification = this.stringToHTML(this.theme.render(envelope))
|
const notification = this.stringToHTML(this.theme.render(envelope))
|
||||||
|
|
||||||
notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' '))
|
notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' '))
|
||||||
@@ -126,4 +133,23 @@ export default class FlasherPlugin extends AbstractPlugin {
|
|||||||
template.innerHTML = str.trim()
|
template.innerHTML = str.trim()
|
||||||
return template.content.firstElementChild as HTMLElement
|
return template.content.firstElementChild as HTMLElement
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private escapeHtml(str: string | null | undefined): string {
|
||||||
|
if (str == null) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
|
return str.replace(/[&<>"'`=\/]/g, (char) => {
|
||||||
|
return {
|
||||||
|
'&': '&',
|
||||||
|
'<': '<',
|
||||||
|
'>': '>',
|
||||||
|
'"': '"',
|
||||||
|
'\'': ''',
|
||||||
|
'`': '`',
|
||||||
|
'=': '=',
|
||||||
|
'/': '/',
|
||||||
|
}[char] as string
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,4 +15,5 @@ export default class FlasherPlugin extends AbstractPlugin {
|
|||||||
}): void;
|
}): void;
|
||||||
private removeNotification;
|
private removeNotification;
|
||||||
private stringToHTML;
|
private stringToHTML;
|
||||||
|
private escapeHtml;
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-2
@@ -92,14 +92,15 @@ class FlasherPlugin extends AbstractPlugin {
|
|||||||
direction: 'top',
|
direction: 'top',
|
||||||
rtl: false,
|
rtl: false,
|
||||||
style: {},
|
style: {},
|
||||||
|
escapeHtml: false,
|
||||||
};
|
};
|
||||||
this.theme = theme;
|
this.theme = theme;
|
||||||
}
|
}
|
||||||
renderEnvelopes(envelopes) {
|
renderEnvelopes(envelopes) {
|
||||||
const render = () => envelopes.forEach((envelope) => {
|
const render = () => envelopes.forEach((envelope) => {
|
||||||
var _a, _b, _c;
|
var _a, _b, _c, _d;
|
||||||
const typeTimeout = (_b = (_a = this.options.timeout) !== null && _a !== void 0 ? _a : this.options.timeouts[envelope.type]) !== null && _b !== void 0 ? _b : 5000;
|
const typeTimeout = (_b = (_a = this.options.timeout) !== null && _a !== void 0 ? _a : this.options.timeouts[envelope.type]) !== null && _b !== void 0 ? _b : 5000;
|
||||||
const options = Object.assign(Object.assign(Object.assign({}, this.options), envelope.options), { timeout: (_c = envelope.options.timeout) !== null && _c !== void 0 ? _c : typeTimeout });
|
const options = Object.assign(Object.assign(Object.assign({}, this.options), envelope.options), { timeout: (_c = envelope.options.timeout) !== null && _c !== void 0 ? _c : typeTimeout, escapeHtml: ((_d = envelope.options.escapeHtml) !== null && _d !== void 0 ? _d : this.options.escapeHtml) });
|
||||||
this.addToContainer(this.createContainer(options), envelope, options);
|
this.addToContainer(this.createContainer(options), envelope, options);
|
||||||
});
|
});
|
||||||
document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', render) : render();
|
document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', render) : render();
|
||||||
@@ -121,6 +122,10 @@ class FlasherPlugin extends AbstractPlugin {
|
|||||||
}
|
}
|
||||||
addToContainer(container, envelope, options) {
|
addToContainer(container, envelope, options) {
|
||||||
var _a;
|
var _a;
|
||||||
|
if (options.escapeHtml) {
|
||||||
|
envelope.title = this.escapeHtml(envelope.title);
|
||||||
|
envelope.message = this.escapeHtml(envelope.message);
|
||||||
|
}
|
||||||
const notification = this.stringToHTML(this.theme.render(envelope));
|
const notification = this.stringToHTML(this.theme.render(envelope));
|
||||||
notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' '));
|
notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' '));
|
||||||
options.direction === 'bottom' ? container.append(notification) : container.prepend(notification);
|
options.direction === 'bottom' ? container.append(notification) : container.prepend(notification);
|
||||||
@@ -170,6 +175,23 @@ class FlasherPlugin extends AbstractPlugin {
|
|||||||
template.innerHTML = str.trim();
|
template.innerHTML = str.trim();
|
||||||
return template.content.firstElementChild;
|
return template.content.firstElementChild;
|
||||||
}
|
}
|
||||||
|
escapeHtml(str) {
|
||||||
|
if (str == null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return str.replace(/[&<>"'`=\/]/g, (char) => {
|
||||||
|
return {
|
||||||
|
'&': '&',
|
||||||
|
'<': '<',
|
||||||
|
'>': '>',
|
||||||
|
'"': '"',
|
||||||
|
'\'': ''',
|
||||||
|
'`': '`',
|
||||||
|
'=': '=',
|
||||||
|
'/': '/',
|
||||||
|
}[char];
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Flasher extends AbstractPlugin {
|
class Flasher extends AbstractPlugin {
|
||||||
|
|||||||
Vendored
+24
-2
@@ -98,14 +98,15 @@
|
|||||||
direction: 'top',
|
direction: 'top',
|
||||||
rtl: false,
|
rtl: false,
|
||||||
style: {},
|
style: {},
|
||||||
|
escapeHtml: false,
|
||||||
};
|
};
|
||||||
this.theme = theme;
|
this.theme = theme;
|
||||||
}
|
}
|
||||||
renderEnvelopes(envelopes) {
|
renderEnvelopes(envelopes) {
|
||||||
const render = () => envelopes.forEach((envelope) => {
|
const render = () => envelopes.forEach((envelope) => {
|
||||||
var _a, _b, _c;
|
var _a, _b, _c, _d;
|
||||||
const typeTimeout = (_b = (_a = this.options.timeout) !== null && _a !== void 0 ? _a : this.options.timeouts[envelope.type]) !== null && _b !== void 0 ? _b : 5000;
|
const typeTimeout = (_b = (_a = this.options.timeout) !== null && _a !== void 0 ? _a : this.options.timeouts[envelope.type]) !== null && _b !== void 0 ? _b : 5000;
|
||||||
const options = Object.assign(Object.assign(Object.assign({}, this.options), envelope.options), { timeout: (_c = envelope.options.timeout) !== null && _c !== void 0 ? _c : typeTimeout });
|
const options = Object.assign(Object.assign(Object.assign({}, this.options), envelope.options), { timeout: (_c = envelope.options.timeout) !== null && _c !== void 0 ? _c : typeTimeout, escapeHtml: ((_d = envelope.options.escapeHtml) !== null && _d !== void 0 ? _d : this.options.escapeHtml) });
|
||||||
this.addToContainer(this.createContainer(options), envelope, options);
|
this.addToContainer(this.createContainer(options), envelope, options);
|
||||||
});
|
});
|
||||||
document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', render) : render();
|
document.readyState === 'loading' ? document.addEventListener('DOMContentLoaded', render) : render();
|
||||||
@@ -127,6 +128,10 @@
|
|||||||
}
|
}
|
||||||
addToContainer(container, envelope, options) {
|
addToContainer(container, envelope, options) {
|
||||||
var _a;
|
var _a;
|
||||||
|
if (options.escapeHtml) {
|
||||||
|
envelope.title = this.escapeHtml(envelope.title);
|
||||||
|
envelope.message = this.escapeHtml(envelope.message);
|
||||||
|
}
|
||||||
const notification = this.stringToHTML(this.theme.render(envelope));
|
const notification = this.stringToHTML(this.theme.render(envelope));
|
||||||
notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' '));
|
notification.classList.add(...`fl-container${options.rtl ? ' fl-rtl' : ''}`.split(' '));
|
||||||
options.direction === 'bottom' ? container.append(notification) : container.prepend(notification);
|
options.direction === 'bottom' ? container.append(notification) : container.prepend(notification);
|
||||||
@@ -176,6 +181,23 @@
|
|||||||
template.innerHTML = str.trim();
|
template.innerHTML = str.trim();
|
||||||
return template.content.firstElementChild;
|
return template.content.firstElementChild;
|
||||||
}
|
}
|
||||||
|
escapeHtml(str) {
|
||||||
|
if (str == null) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return str.replace(/[&<>"'`=\/]/g, (char) => {
|
||||||
|
return {
|
||||||
|
'&': '&',
|
||||||
|
'<': '<',
|
||||||
|
'>': '>',
|
||||||
|
'"': '"',
|
||||||
|
'\'': ''',
|
||||||
|
'`': '`',
|
||||||
|
'=': '=',
|
||||||
|
'/': '/',
|
||||||
|
}[char];
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Flasher extends AbstractPlugin {
|
class Flasher extends AbstractPlugin {
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user