@@ -106,11 +106,24 @@ declare module '@tiptap/core' {
106106
107107// From DOMPurify
108108// https://github.com/cure53/DOMPurify/blob/main/src/regexp.js
109- const ATTR_WHITESPACE = / [ \u0000 - \u0020 \u00A0 \u1680 \u180E \u2000 - \u2029 \u205F \u3000 ] / g // eslint-disable-line no-control-regex
110- const IS_ALLOWED_URI = / ^ (?: (?: (?: f | h t ) t p s ? | m a i l t o | t e l | c a l l t o | s m s | c i d | x m p p ) : | [ ^ a - z ] | [ a - z + . \- ] + (?: [ ^ a - z + . \- : ] | $ ) ) / i // eslint-disable-line no-useless-escape
109+ // eslint-disable-next -line no-control-regex
110+ const ATTR_WHITESPACE = / [ \u0000 - \u0020 \u00A0 \u1680 \u180E \u2000 - \u2029 \u205F \u3000 ] / g
111111
112- function isAllowedUri ( uri : string | undefined ) {
113- return ! uri || uri . replace ( ATTR_WHITESPACE , '' ) . match ( IS_ALLOWED_URI )
112+ function isAllowedUri ( uri : string | undefined , protocols ?: LinkOptions [ 'protocols' ] ) {
113+ const allowedProtocols : string [ ] = [ 'http' , 'https' , 'ftp' , 'ftps' , 'mailto' , 'tel' , 'callto' , 'sms' , 'cid' , 'xmpp' ]
114+
115+ if ( protocols ) {
116+ protocols . forEach ( protocol => {
117+ const nextProtocol = ( typeof protocol === 'string' ? protocol : protocol . scheme )
118+
119+ if ( nextProtocol ) {
120+ allowedProtocols . push ( nextProtocol )
121+ }
122+ } )
123+ }
124+
125+ // eslint-disable-next-line no-useless-escape
126+ return ! uri || uri . replace ( ATTR_WHITESPACE , '' ) . match ( new RegExp ( `^(?:(?:${ allowedProtocols . join ( '|' ) } ):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))` , 'i' ) )
114127}
115128
116129/**
@@ -187,7 +200,7 @@ export const Link = Mark.create<LinkOptions>({
187200 const href = ( dom as HTMLElement ) . getAttribute ( 'href' )
188201
189202 // prevent XSS attacks
190- if ( ! href || ! isAllowedUri ( href ) ) {
203+ if ( ! href || ! isAllowedUri ( href , this . options . protocols ) ) {
191204 return false
192205 }
193206 return null
@@ -197,7 +210,7 @@ export const Link = Mark.create<LinkOptions>({
197210
198211 renderHTML ( { HTMLAttributes } ) {
199212 // prevent XSS attacks
200- if ( ! isAllowedUri ( HTMLAttributes . href ) ) {
213+ if ( ! isAllowedUri ( HTMLAttributes . href , this . options . protocols ) ) {
201214 // strip out the href
202215 return [ 'a' , mergeAttributes ( this . options . HTMLAttributes , { ...HTMLAttributes , href : '' } ) , 0 ]
203216 }
0 commit comments