Add noopener and/or noreferrer (#12202)
This commit is contained in:
		
							parent
							
								
									237293fd8c
								
							
						
					
					
						commit
						fccf83e1f2
					
				
					 27 changed files with 46 additions and 45 deletions
				
			
		| 
						 | 
					@ -25,7 +25,7 @@ export default class AttachmentList extends ImmutablePureComponent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              return (
 | 
					              return (
 | 
				
			||||||
                <li key={attachment.get('id')}>
 | 
					                <li key={attachment.get('id')}>
 | 
				
			||||||
                  <a href={displayUrl} target='_blank' rel='noopener'><Icon id='link' /> {filename(displayUrl)}</a>
 | 
					                  <a href={displayUrl} target='_blank' rel='noopener noreferrer'><Icon id='link' /> {filename(displayUrl)}</a>
 | 
				
			||||||
                </li>
 | 
					                </li>
 | 
				
			||||||
              );
 | 
					              );
 | 
				
			||||||
            })}
 | 
					            })}
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ export default class AttachmentList extends ImmutablePureComponent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return (
 | 
					            return (
 | 
				
			||||||
              <li key={attachment.get('id')}>
 | 
					              <li key={attachment.get('id')}>
 | 
				
			||||||
                <a href={displayUrl} target='_blank' rel='noopener'>{filename(displayUrl)}</a>
 | 
					                <a href={displayUrl} target='_blank' rel='noopener noreferrer'>{filename(displayUrl)}</a>
 | 
				
			||||||
              </li>
 | 
					              </li>
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
          })}
 | 
					          })}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,7 +143,7 @@ class DropdownMenu extends React.PureComponent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <li className='dropdown-menu__item' key={`${text}-${i}`}>
 | 
					      <li className='dropdown-menu__item' key={`${text}-${i}`}>
 | 
				
			||||||
        <a href={href} target={target} data-method={method} rel='noopener' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyPress={this.handleItemKeyPress} data-index={i}>
 | 
					        <a href={href} target={target} data-method={method} rel='noopener noreferrer' role='button' tabIndex='0' ref={i === 0 ? this.setFocusRef : null} onClick={this.handleClick} onKeyPress={this.handleItemKeyPress} data-index={i}>
 | 
				
			||||||
          {text}
 | 
					          {text}
 | 
				
			||||||
        </a>
 | 
					        </a>
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,7 @@ export default class ErrorBoundary extends React.PureComponent {
 | 
				
			||||||
        <div>
 | 
					        <div>
 | 
				
			||||||
          <p className='error-boundary__error'><FormattedMessage id='error.unexpected_crash.explanation' defaultMessage='Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.' /></p>
 | 
					          <p className='error-boundary__error'><FormattedMessage id='error.unexpected_crash.explanation' defaultMessage='Due to a bug in our code or a browser compatibility issue, this page could not be displayed correctly.' /></p>
 | 
				
			||||||
          <p><FormattedMessage id='error.unexpected_crash.next_steps' defaultMessage='Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.' /></p>
 | 
					          <p><FormattedMessage id='error.unexpected_crash.next_steps' defaultMessage='Try refreshing the page. If that does not help, you may still be able to use Mastodon through a different browser or native app.' /></p>
 | 
				
			||||||
          <p className='error-boundary__footer'>Mastodon v{version} · <a href={source_url} rel='noopener' target='_blank'><FormattedMessage id='errors.unexpected_crash.report_issue' defaultMessage='Report issue' /></a> · <button onClick={this.handleCopyStackTrace} className={copied && 'copied'}><FormattedMessage id='errors.unexpected_crash.copy_stacktrace' defaultMessage='Copy stacktrace to clipboard' /></button></p>
 | 
					          <p className='error-boundary__footer'>Mastodon v{version} · <a href={source_url} rel='noopener noreferrer' target='_blank'><FormattedMessage id='errors.unexpected_crash.report_issue' defaultMessage='Report issue' /></a> · <button onClick={this.handleCopyStackTrace} className={copied && 'copied'}><FormattedMessage id='errors.unexpected_crash.copy_stacktrace' defaultMessage='Copy stacktrace to clipboard' /></button></p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -159,7 +159,7 @@ class Item extends React.PureComponent {
 | 
				
			||||||
    if (attachment.get('type') === 'unknown') {
 | 
					    if (attachment.get('type') === 'unknown') {
 | 
				
			||||||
      return (
 | 
					      return (
 | 
				
			||||||
        <div className={classNames('media-gallery__item', { standalone })} key={attachment.get('id')} style={{ left: left, top: top, right: right, bottom: bottom, width: `${width}%`, height: `${height}%` }}>
 | 
					        <div className={classNames('media-gallery__item', { standalone })} key={attachment.get('id')} style={{ left: left, top: top, right: right, bottom: bottom, width: `${width}%`, height: `${height}%` }}>
 | 
				
			||||||
          <a className='media-gallery__item-thumbnail' href={attachment.get('remote_url') || attachment.get('url')} target='_blank' style={{ cursor: 'pointer' }} title={attachment.get('description')}>
 | 
					          <a className='media-gallery__item-thumbnail' href={attachment.get('remote_url') || attachment.get('url')} style={{ cursor: 'pointer' }} title={attachment.get('description')} target='_blank' rel='noopener noreferrer'>
 | 
				
			||||||
            <canvas width={32} height={32} ref={this.setCanvasRef} className='media-gallery__preview' />
 | 
					            <canvas width={32} height={32} ref={this.setCanvasRef} className='media-gallery__preview' />
 | 
				
			||||||
          </a>
 | 
					          </a>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
| 
						 | 
					@ -187,6 +187,7 @@ class Item extends React.PureComponent {
 | 
				
			||||||
          href={attachment.get('remote_url') || originalUrl}
 | 
					          href={attachment.get('remote_url') || originalUrl}
 | 
				
			||||||
          onClick={this.handleClick}
 | 
					          onClick={this.handleClick}
 | 
				
			||||||
          target='_blank'
 | 
					          target='_blank'
 | 
				
			||||||
 | 
					          rel='noopener noreferrer'
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          <img
 | 
					          <img
 | 
				
			||||||
            src={previewUrl}
 | 
					            src={previewUrl}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -437,9 +437,9 @@ class Status extends ImmutablePureComponent {
 | 
				
			||||||
          <div className={classNames('status', `status-${status.get('visibility')}`, { 'status-reply': !!status.get('in_reply_to_id'), muted: this.props.muted, read: unread === false })} data-id={status.get('id')}>
 | 
					          <div className={classNames('status', `status-${status.get('visibility')}`, { 'status-reply': !!status.get('in_reply_to_id'), muted: this.props.muted, read: unread === false })} data-id={status.get('id')}>
 | 
				
			||||||
            <div className='status__expand' onClick={this.handleExpandClick} role='presentation' />
 | 
					            <div className='status__expand' onClick={this.handleExpandClick} role='presentation' />
 | 
				
			||||||
            <div className='status__info'>
 | 
					            <div className='status__info'>
 | 
				
			||||||
              <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
 | 
					              <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              <a onClick={this.handleAccountClick} target='_blank' data-id={status.getIn(['account', 'id'])} href={status.getIn(['account', 'url'])} title={status.getIn(['account', 'acct'])} className='status__display-name'>
 | 
					              <a onClick={this.handleAccountClick} data-id={status.getIn(['account', 'id'])} href={status.getIn(['account', 'url'])} title={status.getIn(['account', 'acct'])} className='status__display-name' target='_blank' rel='noopener noreferrer'>
 | 
				
			||||||
                <div className='status__avatar'>
 | 
					                <div className='status__avatar'>
 | 
				
			||||||
                  {statusAvatar}
 | 
					                  {statusAvatar}
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,7 +59,7 @@ export default class StatusContent extends React.PureComponent {
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      link.setAttribute('target', '_blank');
 | 
					      link.setAttribute('target', '_blank');
 | 
				
			||||||
      link.setAttribute('rel', 'noopener');
 | 
					      link.setAttribute('rel', 'noopener noreferrer');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (
 | 
					    if (
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -253,7 +253,7 @@ class Header extends ImmutablePureComponent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div className='account__header__bar'>
 | 
					        <div className='account__header__bar'>
 | 
				
			||||||
          <div className='account__header__tabs'>
 | 
					          <div className='account__header__tabs'>
 | 
				
			||||||
            <a className='avatar' href={account.get('url')} rel='noopener' target='_blank'>
 | 
					            <a className='avatar' href={account.get('url')} rel='noopener noreferrer' target='_blank'>
 | 
				
			||||||
              <Avatar account={account} size={90} />
 | 
					              <Avatar account={account} size={90} />
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -282,10 +282,10 @@ class Header extends ImmutablePureComponent {
 | 
				
			||||||
                      <dt dangerouslySetInnerHTML={{ __html: proof.get('provider') }} />
 | 
					                      <dt dangerouslySetInnerHTML={{ __html: proof.get('provider') }} />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                      <dd className='verified'>
 | 
					                      <dd className='verified'>
 | 
				
			||||||
                        <a href={proof.get('proof_url')} target='_blank' rel='noopener'><span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(proof.get('updated_at'), dateFormatOptions) })}>
 | 
					                        <a href={proof.get('proof_url')} target='_blank' rel='noopener noreferrer'><span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(proof.get('updated_at'), dateFormatOptions) })}>
 | 
				
			||||||
                          <Icon id='check' className='verified__mark' />
 | 
					                          <Icon id='check' className='verified__mark' />
 | 
				
			||||||
                        </span></a>
 | 
					                        </span></a>
 | 
				
			||||||
                        <a href={proof.get('profile_url')} target='_blank' rel='noopener'><span dangerouslySetInnerHTML={{ __html: ' '+proof.get('provider_username') }} /></a>
 | 
					                        <a href={proof.get('profile_url')} target='_blank' rel='noopener noreferrer'><span dangerouslySetInnerHTML={{ __html: ' '+proof.get('provider_username') }} /></a>
 | 
				
			||||||
                      </dd>
 | 
					                      </dd>
 | 
				
			||||||
                    </dl>
 | 
					                    </dl>
 | 
				
			||||||
                  ))}
 | 
					                  ))}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,12 @@
 | 
				
			||||||
import React from 'react';
 | 
					import { decode } from 'blurhash';
 | 
				
			||||||
import PropTypes from 'prop-types';
 | 
					import classNames from 'classnames';
 | 
				
			||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
 | 
					 | 
				
			||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
 | 
					 | 
				
			||||||
import Icon from 'mastodon/components/icon';
 | 
					import Icon from 'mastodon/components/icon';
 | 
				
			||||||
import { autoPlayGif, displayMedia } from 'mastodon/initial_state';
 | 
					import { autoPlayGif, displayMedia } from 'mastodon/initial_state';
 | 
				
			||||||
import classNames from 'classnames';
 | 
					 | 
				
			||||||
import { decode } from 'blurhash';
 | 
					 | 
				
			||||||
import { isIOS } from 'mastodon/is_mobile';
 | 
					import { isIOS } from 'mastodon/is_mobile';
 | 
				
			||||||
 | 
					import PropTypes from 'prop-types';
 | 
				
			||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import ImmutablePropTypes from 'react-immutable-proptypes';
 | 
				
			||||||
 | 
					import ImmutablePureComponent from 'react-immutable-pure-component';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class MediaItem extends ImmutablePureComponent {
 | 
					export default class MediaItem extends ImmutablePureComponent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,7 +151,7 @@ export default class MediaItem extends ImmutablePureComponent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <div className='account-gallery__item' style={{ width, height }}>
 | 
					      <div className='account-gallery__item' style={{ width, height }}>
 | 
				
			||||||
        <a className='media-gallery__item-thumbnail' href={status.get('url')} target='_blank' onClick={this.handleClick} title={title}>
 | 
					        <a className='media-gallery__item-thumbnail' href={status.get('url')} onClick={this.handleClick} title={title} target='_blank' rel='noopener noreferrer'>
 | 
				
			||||||
          <canvas width={32} height={32} ref={this.setCanvasRef} className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': visible && loaded })} />
 | 
					          <canvas width={32} height={32} ref={this.setCanvasRef} className={classNames('media-gallery__preview', { 'media-gallery__preview--hidden': visible && loaded })} />
 | 
				
			||||||
          {visible && thumbnail}
 | 
					          {visible && thumbnail}
 | 
				
			||||||
          {!visible && icon}
 | 
					          {!visible && icon}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,7 +148,7 @@ export default class Card extends React.PureComponent {
 | 
				
			||||||
    const horizontal  = (!compact && card.get('width') > card.get('height') && (card.get('width') + 100 >= width)) || card.get('type') !== 'link' || embedded;
 | 
					    const horizontal  = (!compact && card.get('width') > card.get('height') && (card.get('width') + 100 >= width)) || card.get('type') !== 'link' || embedded;
 | 
				
			||||||
    const interactive = card.get('type') !== 'link';
 | 
					    const interactive = card.get('type') !== 'link';
 | 
				
			||||||
    const className   = classnames('status-card', { horizontal, compact, interactive });
 | 
					    const className   = classnames('status-card', { horizontal, compact, interactive });
 | 
				
			||||||
    const title       = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
 | 
					    const title       = interactive ? <a className='status-card__title' href={card.get('url')} title={card.get('title')} rel='noopener noreferrer' target='_blank'><strong>{card.get('title')}</strong></a> : <strong className='status-card__title' title={card.get('title')}>{card.get('title')}</strong>;
 | 
				
			||||||
    const ratio       = card.get('width') / card.get('height');
 | 
					    const ratio       = card.get('width') / card.get('height');
 | 
				
			||||||
    const height      = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio);
 | 
					    const height      = (compact && !embedded) ? (width / (16 / 9)) : (width / ratio);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,7 +180,7 @@ export default class Card extends React.PureComponent {
 | 
				
			||||||
            <div className='status-card__actions'>
 | 
					            <div className='status-card__actions'>
 | 
				
			||||||
              <div>
 | 
					              <div>
 | 
				
			||||||
                <button onClick={this.handleEmbedClick}><Icon id={iconVariant} /></button>
 | 
					                <button onClick={this.handleEmbedClick}><Icon id={iconVariant} /></button>
 | 
				
			||||||
                {horizontal && <a href={card.get('url')} target='_blank' rel='noopener'><Icon id='external-link' /></a>}
 | 
					                {horizontal && <a href={card.get('url')} target='_blank' rel='noopener noreferrer'><Icon id='external-link' /></a>}
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
| 
						 | 
					@ -208,7 +208,7 @@ export default class Card extends React.PureComponent {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <a href={card.get('url')} className={className} target='_blank' rel='noopener' ref={this.setRef}>
 | 
					      <a href={card.get('url')} className={className} target='_blank' rel='noopener noreferrer' ref={this.setRef}>
 | 
				
			||||||
        {embed}
 | 
					        {embed}
 | 
				
			||||||
        {description}
 | 
					        {description}
 | 
				
			||||||
      </a>
 | 
					      </a>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,7 +156,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (status.get('application')) {
 | 
					    if (status.get('application')) {
 | 
				
			||||||
      applicationLink = <span> · <a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener'>{status.getIn(['application', 'name'])}</a></span>;
 | 
					      applicationLink = <span> · <a className='detailed-status__application' href={status.getIn(['application', 'website'])} target='_blank' rel='noopener noreferrer'>{status.getIn(['application', 'name'])}</a></span>;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (status.get('visibility') === 'direct') {
 | 
					    if (status.get('visibility') === 'direct') {
 | 
				
			||||||
| 
						 | 
					@ -220,7 +220,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
 | 
				
			||||||
          {media}
 | 
					          {media}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <div className='detailed-status__meta'>
 | 
					          <div className='detailed-status__meta'>
 | 
				
			||||||
            <a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener'>
 | 
					            <a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener noreferrer'>
 | 
				
			||||||
              <FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
 | 
					              <FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
 | 
				
			||||||
            </a>{applicationLink} · {reblogLink} · {favouriteLink}
 | 
					            </a>{applicationLink} · {reblogLink} · {favouriteLink}
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ export default class ActionsModal extends ImmutablePureComponent {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <li key={`${text}-${i}`}>
 | 
					      <li key={`${text}-${i}`}>
 | 
				
			||||||
        <a href={href} target='_blank' rel='noopener' onClick={this.props.onClick} data-index={i} className={classNames({ active })}>
 | 
					        <a href={href} target='_blank' rel='noopener noreferrer' onClick={this.props.onClick} data-index={i} className={classNames({ active })}>
 | 
				
			||||||
          {icon && <IconButton title={text} icon={icon} role='presentation' tabIndex='-1' inverted />}
 | 
					          {icon && <IconButton title={text} icon={icon} role='presentation' tabIndex='-1' inverted />}
 | 
				
			||||||
          <div>
 | 
					          <div>
 | 
				
			||||||
            <div className={classNames({ 'actions-modal__item-label': !!meta })}>{text}</div>
 | 
					            <div className={classNames({ 'actions-modal__item-label': !!meta })}>{text}</div>
 | 
				
			||||||
| 
						 | 
					@ -42,7 +42,7 @@ export default class ActionsModal extends ImmutablePureComponent {
 | 
				
			||||||
      <div className='status light'>
 | 
					      <div className='status light'>
 | 
				
			||||||
        <div className='boost-modal__status-header'>
 | 
					        <div className='boost-modal__status-header'>
 | 
				
			||||||
          <div className='boost-modal__status-time'>
 | 
					          <div className='boost-modal__status-time'>
 | 
				
			||||||
            <a href={this.props.status.get('url')} className='status__relative-time' target='_blank' rel='noopener'>
 | 
					            <a href={this.props.status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'>
 | 
				
			||||||
              <RelativeTimestamp timestamp={this.props.status.get('created_at')} />
 | 
					              <RelativeTimestamp timestamp={this.props.status.get('created_at')} />
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,7 +61,7 @@ class BoostModal extends ImmutablePureComponent {
 | 
				
			||||||
          <div className='status light'>
 | 
					          <div className='status light'>
 | 
				
			||||||
            <div className='boost-modal__status-header'>
 | 
					            <div className='boost-modal__status-header'>
 | 
				
			||||||
              <div className='boost-modal__status-time'>
 | 
					              <div className='boost-modal__status-time'>
 | 
				
			||||||
                <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
 | 
					                <a href={status.get('url')} className='status__relative-time' target='_blank' rel='noopener noreferrer'><RelativeTimestamp timestamp={status.get('created_at')} /></a>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              <a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name'>
 | 
					              <a onClick={this.handleAccountClick} href={status.getIn(['account', 'url'])} className='status__display-name'>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -62,7 +62,7 @@ class LinkFooter extends React.PureComponent {
 | 
				
			||||||
          <FormattedMessage
 | 
					          <FormattedMessage
 | 
				
			||||||
            id='getting_started.open_source_notice'
 | 
					            id='getting_started.open_source_notice'
 | 
				
			||||||
            defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.'
 | 
					            defaultMessage='Mastodon is open source software. You can contribute or report issues on GitHub at {github}.'
 | 
				
			||||||
            values={{ github: <span><a href={source_url} rel='noopener' target='_blank'>{repository}</a> (v{version})</span> }}
 | 
					            values={{ github: <span><a href={source_url} rel='noopener noreferrer' target='_blank'>{repository}</a> (v{version})</span> }}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
        </p>
 | 
					        </p>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -251,7 +251,7 @@ class Formatter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def link_to_url(entity, options = {})
 | 
					  def link_to_url(entity, options = {})
 | 
				
			||||||
    url        = Addressable::URI.parse(entity[:url])
 | 
					    url        = Addressable::URI.parse(entity[:url])
 | 
				
			||||||
    html_attrs = { target: '_blank', rel: 'nofollow noopener' }
 | 
					    html_attrs = { target: '_blank', rel: 'nofollow noopener noreferrer' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    html_attrs[:rel] = "me #{html_attrs[:rel]}" if options[:me]
 | 
					    html_attrs[:rel] = "me #{html_attrs[:rel]}" if options[:me]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,7 +45,7 @@ class Sanitize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      add_attributes: {
 | 
					      add_attributes: {
 | 
				
			||||||
        'a' => {
 | 
					        'a' => {
 | 
				
			||||||
          'rel' => 'nofollow noopener',
 | 
					          'rel' => 'nofollow noopener noreferrer',
 | 
				
			||||||
          'target' => '_blank',
 | 
					          'target' => '_blank',
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,7 @@
 | 
				
			||||||
                %small= t('about.browse_public_posts')
 | 
					                %small= t('about.browse_public_posts')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .directory__tag
 | 
					        .directory__tag
 | 
				
			||||||
          = link_to 'https://joinmastodon.org/apps', target: '_blank', rel: 'noopener' do
 | 
					          = link_to 'https://joinmastodon.org/apps', target: '_blank', rel: 'noopener noreferrer' do
 | 
				
			||||||
            %h4
 | 
					            %h4
 | 
				
			||||||
              = fa_icon 'tablet fw'
 | 
					              = fa_icon 'tablet fw'
 | 
				
			||||||
              = t('about.get_apps')
 | 
					              = t('about.get_apps')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@
 | 
				
			||||||
    = t('accounts.moved_html', name: content_tag(:bdi, content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify)), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), ActivityPub::TagManager.instance.url_for(moved_to_account), class: 'mention'))
 | 
					    = t('accounts.moved_html', name: content_tag(:bdi, content_tag(:strong, display_name(account, custom_emojify: true), class: :emojify)), new_profile_link: link_to(content_tag(:strong, safe_join(['@', content_tag(:span, moved_to_account.acct)])), ActivityPub::TagManager.instance.url_for(moved_to_account), class: 'mention'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .moved-account-widget__card
 | 
					  .moved-account-widget__card
 | 
				
			||||||
    = link_to ActivityPub::TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'me noopener' do
 | 
					    = link_to ActivityPub::TagManager.instance.url_for(moved_to_account), class: 'detailed-status__display-name p-author h-card', target: '_blank', rel: 'me noopener noreferrer' do
 | 
				
			||||||
      .detailed-status__display-avatar
 | 
					      .detailed-status__display-avatar
 | 
				
			||||||
        .account__avatar-overlay
 | 
					        .account__avatar-overlay
 | 
				
			||||||
          .account__avatar-overlay-base{ style: "background-image: url('#{moved_to_account.avatar.url(:original)}')" }
 | 
					          .account__avatar-overlay-base{ style: "background-image: url('#{moved_to_account.avatar.url(:original)}')" }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@
 | 
				
			||||||
        = react_component :media_gallery, height: 343, sensitive: !current_account&.user&.show_all_media? && status.proper.sensitive? || current_account&.user&.hide_all_media?, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
 | 
					        = react_component :media_gallery, height: 343, sensitive: !current_account&.user&.show_all_media? && status.proper.sensitive? || current_account&.user&.hide_all_media?, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.proper.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .detailed-status__meta
 | 
					    .detailed-status__meta
 | 
				
			||||||
      = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener' do
 | 
					      = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener noreferrer' do
 | 
				
			||||||
        %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
 | 
					        %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
 | 
				
			||||||
      - if status.discarded?
 | 
					      - if status.discarded?
 | 
				
			||||||
        ·
 | 
					        ·
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.dashboard__counters
 | 
					.dashboard__counters
 | 
				
			||||||
  %div
 | 
					  %div
 | 
				
			||||||
    = link_to tag_url(@tag), target: '_blank', rel: 'noopener' do
 | 
					    = link_to tag_url(@tag), target: '_blank', rel: 'noopener noreferrer' do
 | 
				
			||||||
      .dashboard__counters__num= number_with_delimiter @accounts_today
 | 
					      .dashboard__counters__num= number_with_delimiter @accounts_today
 | 
				
			||||||
      .dashboard__counters__label= t 'admin.tags.accounts_today'
 | 
					      .dashboard__counters__label= t 'admin.tags.accounts_today'
 | 
				
			||||||
  %div
 | 
					  %div
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
- account_url = local_assigns[:admin] ? admin_account_path(account.id) : ActivityPub::TagManager.instance.url_for(account)
 | 
					- account_url = local_assigns[:admin] ? admin_account_path(account.id) : ActivityPub::TagManager.instance.url_for(account)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.card.h-card
 | 
					.card.h-card
 | 
				
			||||||
  = link_to account_url, target: '_blank', rel: 'noopener' do
 | 
					  = link_to account_url, target: '_blank', rel: 'noopener noreferrer' do
 | 
				
			||||||
    .card__img
 | 
					    .card__img
 | 
				
			||||||
      = image_tag account.header.url, alt: ''
 | 
					      = image_tag account.header.url, alt: ''
 | 
				
			||||||
    .card__bar
 | 
					    .card__bar
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@
 | 
				
			||||||
            - if application.website.blank?
 | 
					            - if application.website.blank?
 | 
				
			||||||
              = application.name
 | 
					              = application.name
 | 
				
			||||||
            - else
 | 
					            - else
 | 
				
			||||||
              = link_to application.name, application.website, target: '_blank', rel: 'noopener'
 | 
					              = link_to application.name, application.website, target: '_blank', rel: 'noopener noreferrer'
 | 
				
			||||||
          %th!= application.scopes.map { |scope| t(scope, scope: [:doorkeeper, :scopes]) }.join(', ')
 | 
					          %th!= application.scopes.map { |scope| t(scope, scope: [:doorkeeper, :scopes]) }.join(', ')
 | 
				
			||||||
          %td= l application.created_at
 | 
					          %td= l application.created_at
 | 
				
			||||||
          %td
 | 
					          %td
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,14 +44,14 @@
 | 
				
			||||||
  .detailed-status__meta
 | 
					  .detailed-status__meta
 | 
				
			||||||
    %data.dt-published{ value: status.created_at.to_time.iso8601 }
 | 
					    %data.dt-published{ value: status.created_at.to_time.iso8601 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime u-url u-uid', target: stream_link_target, rel: 'noopener' do
 | 
					    = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime u-url u-uid', target: stream_link_target, rel: 'noopener noreferrer' do
 | 
				
			||||||
      %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
 | 
					      %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
 | 
				
			||||||
    ·
 | 
					    ·
 | 
				
			||||||
    - if status.application && @account.user&.setting_show_application
 | 
					    - if status.application && @account.user&.setting_show_application
 | 
				
			||||||
      - if status.application.website.blank?
 | 
					      - if status.application.website.blank?
 | 
				
			||||||
        %strong.detailed-status__application= status.application.name
 | 
					        %strong.detailed-status__application= status.application.name
 | 
				
			||||||
      - else
 | 
					      - else
 | 
				
			||||||
        = link_to status.application.name, status.application.website, class: 'detailed-status__application', target: '_blank', rel: 'noopener'
 | 
					        = link_to status.application.name, status.application.website, class: 'detailed-status__application', target: '_blank', rel: 'noopener noreferrer'
 | 
				
			||||||
      ·
 | 
					      ·
 | 
				
			||||||
    = link_to remote_interaction_path(status, type: :reply), class: 'modal-button detailed-status__link' do
 | 
					    = link_to remote_interaction_path(status, type: :reply), class: 'modal-button detailed-status__link' do
 | 
				
			||||||
      - if status.in_reply_to_id.nil?
 | 
					      - if status.in_reply_to_id.nil?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,11 @@
 | 
				
			||||||
.status
 | 
					.status
 | 
				
			||||||
  .status__info
 | 
					  .status__info
 | 
				
			||||||
    = link_to ActivityPub::TagManager.instance.url_for(status), class: 'status__relative-time u-url u-uid', target: stream_link_target, rel: 'noopener' do
 | 
					    = link_to ActivityPub::TagManager.instance.url_for(status), class: 'status__relative-time u-url u-uid', target: stream_link_target, rel: 'noopener noreferrer' do
 | 
				
			||||||
      %time.time-ago{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
 | 
					      %time.time-ago{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
 | 
				
			||||||
    %data.dt-published{ value: status.created_at.to_time.iso8601 }
 | 
					    %data.dt-published{ value: status.created_at.to_time.iso8601 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .p-author.h-card
 | 
					    .p-author.h-card
 | 
				
			||||||
      = link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'status__display-name u-url', target: stream_link_target, rel: 'noopener' do
 | 
					      = link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'status__display-name u-url', target: stream_link_target, rel: 'noopener noreferrer' do
 | 
				
			||||||
        .status__avatar
 | 
					        .status__avatar
 | 
				
			||||||
          %div
 | 
					          %div
 | 
				
			||||||
            - if current_account&.user&.setting_auto_play_gif || autoplay
 | 
					            - if current_account&.user&.setting_auto_play_gif || autoplay
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								spec/fixtures/xml/mastodon.atom
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								spec/fixtures/xml/mastodon.atom
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -123,7 +123,7 @@
 | 
				
			||||||
    <published>2016-10-10T00:41:31Z</published>
 | 
					    <published>2016-10-10T00:41:31Z</published>
 | 
				
			||||||
    <updated>2016-10-10T00:41:31Z</updated>
 | 
					    <updated>2016-10-10T00:41:31Z</updated>
 | 
				
			||||||
    <title>Social media needs MOAR cats! http://kickass.zone/media/3</title>
 | 
					    <title>Social media needs MOAR cats! http://kickass.zone/media/3</title>
 | 
				
			||||||
    <content type="html"><p>Social media needs MOAR cats! <a rel="nofollow noopener" href="http://kickass.zone/media/3">http://kickass.zone/media/3</a></p></content>
 | 
					    <content type="html"><p>Social media needs MOAR cats! <a rel="nofollow noopener noreferrer" href="http://kickass.zone/media/3">http://kickass.zone/media/3</a></p></content>
 | 
				
			||||||
    <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
 | 
					    <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
 | 
				
			||||||
    <link rel="self" type="application/atom+xml" href="http://kickass.zone/users/localhost/updates/9.atom"/>
 | 
					    <link rel="self" type="application/atom+xml" href="http://kickass.zone/users/localhost/updates/9.atom"/>
 | 
				
			||||||
    <link rel="alternate" type="text/html" href="http://kickass.zone/users/localhost/updates/9"/>
 | 
					    <link rel="alternate" type="text/html" href="http://kickass.zone/users/localhost/updates/9"/>
 | 
				
			||||||
| 
						 | 
					@ -135,7 +135,7 @@
 | 
				
			||||||
    <published>2016-10-10T00:38:39Z</published>
 | 
					    <published>2016-10-10T00:38:39Z</published>
 | 
				
			||||||
    <updated>2016-10-10T00:38:39Z</updated>
 | 
					    <updated>2016-10-10T00:38:39Z</updated>
 | 
				
			||||||
    <title>http://kickass.zone/media/2</title>
 | 
					    <title>http://kickass.zone/media/2</title>
 | 
				
			||||||
    <content type="html"><p><a rel="nofollow noopener" href="http://kickass.zone/media/2">http://kickass.zone/media/2</a></p></content>
 | 
					    <content type="html"><p><a rel="nofollow noopener noreferrer" href="http://kickass.zone/media/2">http://kickass.zone/media/2</a></p></content>
 | 
				
			||||||
    <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
 | 
					    <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
 | 
				
			||||||
    <link rel="self" type="application/atom+xml" href="http://kickass.zone/users/localhost/updates/8.atom"/>
 | 
					    <link rel="self" type="application/atom+xml" href="http://kickass.zone/users/localhost/updates/8.atom"/>
 | 
				
			||||||
    <link rel="alternate" type="text/html" href="http://kickass.zone/users/localhost/updates/8"/>
 | 
					    <link rel="alternate" type="text/html" href="http://kickass.zone/users/localhost/updates/8"/>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ describe Sanitize::Config do
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'keep links in lists' do
 | 
					    it 'keep links in lists' do
 | 
				
			||||||
      expect(Sanitize.fragment('<p>Check out:</p><ul><li><a href="https://joinmastodon.org" rel="nofollow noopener" target="_blank">joinmastodon.org</a></li><li>Bar</li></ul>', subject)).to eq '<p>Check out:</p><p><a href="https://joinmastodon.org" rel="nofollow noopener" target="_blank">joinmastodon.org</a><br>Bar</p>'
 | 
					      expect(Sanitize.fragment('<p>Check out:</p><ul><li><a href="https://joinmastodon.org" rel="nofollow noopener noreferrer" target="_blank">joinmastodon.org</a></li><li>Bar</li></ul>', subject)).to eq '<p>Check out:</p><p><a href="https://joinmastodon.org" rel="nofollow noopener noreferrer" target="_blank">joinmastodon.org</a><br>Bar</p>'
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -80,7 +80,7 @@ RSpec.describe FetchLinkCardService, type: :service do
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  context 'in a remote status' do
 | 
					  context 'in a remote status' do
 | 
				
			||||||
    let(:status) { Fabricate(:status, account: Fabricate(:account, domain: 'example.com'), text: 'Habt ihr ein paar gute Links zu #<span class="tag"><a href="https://quitter.se/tag/wannacry" target="_blank" rel="tag noopener" title="https://quitter.se/tag/wannacry">Wannacry</a></span> herumfliegen?   Ich will mal unter <br> <a href="https://github.com/qbi/WannaCry" target="_blank" rel="noopener" title="https://github.com/qbi/WannaCry">https://github.com/qbi/WannaCry</a> was sammeln. !<a href="http://sn.jonkman.ca/group/416/id" target="_blank" rel="noopener" title="http://sn.jonkman.ca/group/416/id">security</a> ') }
 | 
					    let(:status) { Fabricate(:status, account: Fabricate(:account, domain: 'example.com'), text: 'Habt ihr ein paar gute Links zu #<span class="tag"><a href="https://quitter.se/tag/wannacry" target="_blank" rel="tag noopener noreferrer" title="https://quitter.se/tag/wannacry">Wannacry</a></span> herumfliegen?   Ich will mal unter <br> <a href="https://github.com/qbi/WannaCry" target="_blank" rel="noopener noreferrer" title="https://github.com/qbi/WannaCry">https://github.com/qbi/WannaCry</a> was sammeln. !<a href="http://sn.jonkman.ca/group/416/id" target="_blank" rel="noopener noreferrer" title="http://sn.jonkman.ca/group/416/id">security</a> ') }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it 'parses out URLs' do
 | 
					    it 'parses out URLs' do
 | 
				
			||||||
      expect(a_request(:get, 'https://github.com/qbi/WannaCry')).to have_been_made.at_least_once
 | 
					      expect(a_request(:get, 'https://github.com/qbi/WannaCry')).to have_been_made.at_least_once
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,12 +28,12 @@ RSpec.describe VerifyLinkService, type: :service do
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'when a link contains an <a rel="noopener"> back' do
 | 
					    context 'when a link contains an <a rel="noopener noreferrer"> back' do
 | 
				
			||||||
      let(:html) do
 | 
					      let(:html) do
 | 
				
			||||||
        <<-HTML
 | 
					        <<-HTML
 | 
				
			||||||
          <!doctype html>
 | 
					          <!doctype html>
 | 
				
			||||||
          <body>
 | 
					          <body>
 | 
				
			||||||
            <a href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="noopener me" target="_blank">Follow me on Mastodon</a>
 | 
					            <a href="#{ActivityPub::TagManager.instance.url_for(account)}" rel="me noopener noreferrer" target="_blank">Follow me on Mastodon</a>
 | 
				
			||||||
          </body>
 | 
					          </body>
 | 
				
			||||||
        HTML
 | 
					        HTML
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue