diff --git a/securedrop/sass/modules/_aside.sass b/securedrop/sass/modules/_aside.sass index 27d6bdc1b6..26ff8a1068 100644 --- a/securedrop/sass/modules/_aside.sass +++ b/securedrop/sass/modules/_aside.sass @@ -1,9 +1,9 @@ =aside - aside + .aside background-color: #fffbe6 color: #82572d border-radius: 10px - padding: 10px + padding: 10px + 2*8px // cf. hr.no-line margin: 10px text-align: left font-size: medium diff --git a/securedrop/sass/modules/_center-text-align.sass b/securedrop/sass/modules/_center-text-align.sass index 2c4d4c6061..be0dfec1bf 100644 --- a/securedrop/sass/modules/_center-text-align.sass +++ b/securedrop/sass/modules/_center-text-align.sass @@ -1,5 +1,6 @@ =center-text-align .center + clear: both text-align: center .highlight diff --git a/securedrop/sass/modules/_code.sass b/securedrop/sass/modules/_code.sass index 0af9547de1..3111726901 100644 --- a/securedrop/sass/modules/_code.sass +++ b/securedrop/sass/modules/_code.sass @@ -1,9 +1,21 @@ =code + .code, .code-reminder + background: + image: url(/static/i/font-awesome/lock-black.png) + origin: content-box + repeat: no-repeat + size: 20px 23px + .code - background: rgba(0, 0, 0, 0.05) + background: + color: rgba(0, 0, 0, 0.05) box-sizing: border-box -moz-box-sizing: border-box padding: 10px 15px border-bottom: 2px solid $color_warning_red font-size: large text-align: center + + .code-reminder + background: + size: 17px 20px \ No newline at end of file diff --git a/securedrop/sass/modules/_flash.sass b/securedrop/sass/modules/_flash.sass index 49dfa914d2..a4c2c8b25f 100644 --- a/securedrop/sass/modules/_flash.sass +++ b/securedrop/sass/modules/_flash.sass @@ -1,4 +1,10 @@ =flash + #flashed + margin-top: 0 + + ul + padding: 0 + .flash display: flex flex-flow: row nowrap @@ -9,6 +15,10 @@ text-align: left font-size: medium + background-position-y: center + background-position-x: 10px + background-repeat: no-repeat + &:dir(rtl) text-align: right @@ -18,22 +28,36 @@ &.success border: 1px solid #E1F1E5 background-color: #E6FFEB + background-image: url(/static/i/success_checkmark.png) + background-repeat: no-repeat + background-size: 74px 64px + padding-left: 10px + 74px strong color: #299549 + h2 + color: #299549 + font-size: medium + &.notification border: 1px solid #8ed9f6 background-color: #e3f7fc + background-image: url(/static/i/font-awesome/info-circle-black.png) + background-size: 20px 16px font-size: medium font-weight: normal + padding-left: 10px + 20px i color: #4f7685 - &.error + &.error, &.banner-warning border: 1px solid $color_error_border background-color: $color_error_background + background-image: url(/static/i/font-awesome/exclamation-triangle-black.png) + background-size: 20px 17px + padding-left: 10px + 20px i color: #D62727 @@ -52,6 +76,9 @@ padding-left: 20px padding-right: 8px background-color: #FDFDFD + background-image: url(/static/i/bang-stop.png) + background-size: 22px 22px + padding-left: 10px + 22px color: #383838 align-items: center diff --git a/securedrop/sass/modules/_footer.sass b/securedrop/sass/modules/_footer.sass index d25859746c..08ce20e31d 100644 --- a/securedrop/sass/modules/_footer.sass +++ b/securedrop/sass/modules/_footer.sass @@ -7,10 +7,29 @@ font-size: .8em line-height: 1 + // Avoid squeezing the separator into the content layout in mobile view + margin-top: 2.5em + border-top: solid 1px $color_grimace_grey + + footer p + margin-top: 0 + footer #footer-powered-by color: #373737 margin-bottom: 0.5em + &:before + content: "" + + display: inline-block + height: 23px + width: 20px + vertical-align: middle + + background: + image: url(/static/i/logo-footer.png) + size: 20px 23px + footer #footer-advisory color: #3b3b3b line-height: 1.25 diff --git a/securedrop/sass/modules/_form-validation-error.sass b/securedrop/sass/modules/_form-validation-error.sass index b34bceb40f..6507f351c3 100644 --- a/securedrop/sass/modules/_form-validation-error.sass +++ b/securedrop/sass/modules/_form-validation-error.sass @@ -1,4 +1,5 @@ =form-validation-error - span.form-validation-error + .form-validation-error color: red font-size: small + list-style: none diff --git a/securedrop/sass/modules/_header.sass b/securedrop/sass/modules/_header.sass index c286edee11..4d43fb76b9 100644 --- a/securedrop/sass/modules/_header.sass +++ b/securedrop/sass/modules/_header.sass @@ -1,5 +1,5 @@ =header - #header + header float: left &:dir(rtl) @@ -12,3 +12,7 @@ text-align: center color: #666666 letter-spacing: normal + + h1 + margin: 0 + text-align: center \ No newline at end of file diff --git a/securedrop/sass/modules/_headline.sass b/securedrop/sass/modules/_headline.sass index 385433dbcb..1582889487 100644 --- a/securedrop/sass/modules/_headline.sass +++ b/securedrop/sass/modules/_headline.sass @@ -6,6 +6,7 @@ h1 text-align: left font-size: 30px + padding-top: 10px + 2*8px // cf. hr.no-line &:dir(rtl) text-align: right diff --git a/securedrop/sass/modules/_hr-horizontal-rule-line.sass b/securedrop/sass/modules/_hr-horizontal-rule-line.sass index 176f7ca6a6..9bfe94bec5 100644 --- a/securedrop/sass/modules/_hr-horizontal-rule-line.sass +++ b/securedrop/sass/modules/_hr-horizontal-rule-line.sass @@ -5,16 +5,6 @@ border-bottom: none border-color: #c3c3c3 - &.footer-separator - // Avoid squeezing the separator into the content layout in mobile view - clear: both - width: 100% - margin-top: 2.5em - margin-bottom: 0 - height: 1px - border: none - background: $color_grimace_grey - &.no-line clear: both border: none diff --git a/securedrop/sass/modules/_locales.sass b/securedrop/sass/modules/_locales.sass new file mode 100644 index 0000000000..d1cc356f59 --- /dev/null +++ b/securedrop/sass/modules/_locales.sass @@ -0,0 +1,28 @@ +#locale-menu-trigger + &:before + content: "" + + display: inline-block + height: 18px + width: 18px + + margin-right: 1ch + + background: + image: url(/static/i/languages_globe.png) + size: 18px 18px + + &:after + content: "" + + display: inline + height: 18px + width: 12px + + margin-left: auto + + background: + image: url(/static/i/languages_arrow.png) + position: center + repeat: no-repeat + size: contain \ No newline at end of file diff --git a/securedrop/sass/modules/_menu.sass b/securedrop/sass/modules/_menu.sass index 279613c671..b7a591d0b2 100644 --- a/securedrop/sass/modules/_menu.sass +++ b/securedrop/sass/modules/_menu.sass @@ -77,7 +77,7 @@ &:hover, &:focus, &:active background-color: #e8e8e8 -.menu__item a span +.menu__item a text-transform: capitalize .menu__checkbox:checked ~ .menu__items diff --git a/securedrop/sass/modules/_panel.sass b/securedrop/sass/modules/_panel.sass index 0f9486f249..37a03b97e9 100644 --- a/securedrop/sass/modules/_panel.sass +++ b/securedrop/sass/modules/_panel.sass @@ -1,8 +1,13 @@ =panel - .panel - max-width: 800px - width: 100% - margin: 0 auto - padding: 16px 30px - border: 1px solid #e1e1e1 - float: right + body:not(#source-index) + main + max-width: 800px + width: 100% + margin: 0 auto + padding: 16px 30px + border: 1px solid #e1e1e1 + float: right + + section, article, .section-spacing + display: flow-root + margin-top: 10px + 2*8px // cf. hr.no-line \ No newline at end of file diff --git a/securedrop/sass/modules/_snippet.sass b/securedrop/sass/modules/_snippet.sass index fef1e030b0..a3c9d29e18 100644 --- a/securedrop/sass/modules/_snippet.sass +++ b/securedrop/sass/modules/_snippet.sass @@ -22,6 +22,22 @@ min-width: 100% max-width: 100% + span.fh:before + content: "" + + display: block + width: 100% + height: 56px + margin: + top: 5px + bottom: 10px + + background: + image: url(/static/i/arrow-upload-large.png) + position: center + repeat: no-repeat + size: 56px 56px + .message display: inline-block vertical-align: top diff --git a/securedrop/sass/modules/_warning.sass b/securedrop/sass/modules/_warning.sass index c830705f58..f5019a7b4c 100644 --- a/securedrop/sass/modules/_warning.sass +++ b/securedrop/sass/modules/_warning.sass @@ -15,3 +15,20 @@ .close cursor: pointer + + p + margin: 0 + + &:before + content: "" + + display: inline-block + height: 12px + width: 12px + vertical-align: middle + + margin-right: 1ch + + background: + image: url(/static/i/font-awesome/white/exclamation-circle.svg) + size: 12px 12px \ No newline at end of file diff --git a/securedrop/sass/source.sass b/securedrop/sass/source.sass index b5906f15db..c2c4b25b5f 100644 --- a/securedrop/sass/source.sass +++ b/securedrop/sass/source.sass @@ -2,6 +2,7 @@ @import source_index @import modules/visually-hidden @import modules/menu +@import modules/locales @import modules/flash +base_rules @@ -24,45 +25,42 @@ display: block #codename-hint - background: rgba(0, 0, 0, 0.05) + background: + color: rgba(0, 0, 0, 0.05) box-sizing: border-box -moz-box-sizing: border-box - margin-top: 5px + margin-top: 5px !important padding: 5px 10px text-align: center width: 80% -@media only screen and (max-width: 880px) +@media only screen #codename-hint - width: 100% + summary + cursor: pointer -#codename-hint-visible - .visible-codename - margin: auto - padding: auto - height: auto - overflow: visible + &:after + content: "Show" + display: block + float: right - .hidden-codename - margin: 0 - padding: 0 - height: 0 - overflow: hidden + text-decoration: none + color: $color_securedrop_blue + border-bottom: 1px solid rgba(0, 117, 247, 0.4) - &:target + &:hover, &:active + &:after + color: $color_grimace_blue + border-bottom: 1px solid rgba(42, 49, 157, 1) - .visible-codename - margin: 0 - padding: 0 - height: 0 - overflow: hidden - border: 0 + &[open] + summary + &:after + content: "Hide" - .hidden-codename - margin: auto - padding: auto - height: auto - overflow: visible +@media only screen and (max-width: 880px) + #codename-hint + width: 100% input.codename-box width: 100% @@ -70,6 +68,7 @@ input.codename-box font-weight: bold .codename + background-color: transparent font-family: monospace letter-spacing: 0.15em font-weight: normal @@ -105,17 +104,23 @@ p#codename width: 80% .hidden-prompt + display: block + border: none margin: 0 padding: 0 height: 0 overflow: hidden text-align: center + visibility: hidden + width: 80% + position: static &:target margin: auto padding: auto height: auto overflow: visible + visibility: visible .danger display: inline-block @@ -152,17 +157,38 @@ p#codename font-size: 10px font-weight: bold padding: 5px + margin: 0 a.delete float: right padding: 5px background-color: inherit color: $color_urgent_coral - font-size: 14px + font-size: 0 clear: right text-decoration: none border: 0 + span + font-size: 0 + + &:after + content: "" + display: inline-block + background: + image: url(/static/i/trash-x-out.png) + position: center + repeat: no-repeat + size: contain + opacity: 0.9 + height: 16px + width: 20px + + &:hover, &:active + &:after + background: + image: url(/static/i/trash-x-solid.png) + &:hover color: #FA6E6E @@ -174,6 +200,7 @@ p#codename font-size: 14px background: white border: 1px solid $color_grey_dark + padding: 0 p * @@ -188,12 +215,17 @@ p#codename margin: 0 2% padding: 5px 15px -h4#no-replies - text-align: center - color: $color_grey_medium - background: $color_grey_xlight - padding: 40px - margin: 0.5em 0 + #no-replies + display: block + font-weight: bold + text-align: center + color: $color_grey_medium + background: $color_grey_xlight + padding: 40px + margin: 0.5em 0 + + &:before, &:after + content: " — " p.explanation text-align: left @@ -221,7 +253,7 @@ p#max-file-size font-style: italic margin-bottom: 0 -div.bubble +.bubble width: 415px position: absolute background-color: #ffffff @@ -241,3 +273,52 @@ div.bubble image-rendering: crisp-edges margin-bottom: 10px margin-top: 5px + +#regenerate-submit + span + font-size: 0 + + &:after + content: "" + display: inline-block + background: + image: url(/static/i/font-awesome/refresh-white.png) + position: center + repeat: no-repeat + size: contain + opacity: 0.9 + height: 20px + width: 20px + +#cancel + &:before + content: "" + display: inline-block + background: + image: url(/static/i/x_icon-button_blue.png) + origin: content-box + position: center + repeat: no-repeat + size: contain + width: 9px + height: 11px + + &:hover, &:active + &:before + background: + image: url(/static/i/x_icon-grimace_blue.png) + +.back-arrow + display: inline-block + + &:before + content: "" + + display: inline-block + width: 9px + height: 14px + margin-right: 1ch + + background: + image: url(/static/icons/chevron-left.png) + size: contain \ No newline at end of file diff --git a/securedrop/source_app/forms.py b/securedrop/source_app/forms.py index 75bd70bc35..90701dc035 100644 --- a/securedrop/source_app/forms.py +++ b/securedrop/source_app/forms.py @@ -24,8 +24,9 @@ class LoginForm(FlaskForm): class SubmissionForm(FlaskForm): - msg = TextAreaField("msg", render_kw={"placeholder": gettext("Write a message.")}) - fh = FileField("fh") + msg = TextAreaField("msg", render_kw={"placeholder": gettext("Write a message."), + "aria-label": gettext("Write a message.")}) + fh = FileField("fh", render_kw={"aria-label": gettext("Select a file to upload.")}) def validate_msg(self, field: wtforms.Field) -> None: if len(field.data) > Submission.MAX_MESSAGE_LEN: diff --git a/securedrop/source_app/main.py b/securedrop/source_app/main.py index cbd1a27769..8739869905 100644 --- a/securedrop/source_app/main.py +++ b/securedrop/source_app/main.py @@ -158,7 +158,7 @@ def submit() -> werkzeug.Response: for field, errors in form.errors.items(): for error in errors: flash(error, "error") - return redirect(url_for('main.lookup')) + return redirect(f"{url_for('main.lookup')}#flashed") msg = request.form['msg'] fh = None @@ -173,7 +173,7 @@ def submit() -> werkzeug.Response: "error") else: flash(gettext("You must enter a message."), "error") - return redirect(url_for('main.lookup')) + return redirect(f"{url_for('main.lookup')}#flashed") fnames = [] journalist_filename = g.source.journalist_filename @@ -236,7 +236,7 @@ def submit() -> werkzeug.Response: normalize_timestamps(g.filesystem_id) - return redirect(url_for('main.lookup')) + return redirect(f"{url_for('main.lookup')}#flashed") @view.route('/delete', methods=('POST',)) @login_required diff --git a/securedrop/source_templates/banner_warning_flashed.html b/securedrop/source_templates/banner_warning_flashed.html index 163a37577c..01350b2953 100644 --- a/securedrop/source_templates/banner_warning_flashed.html +++ b/securedrop/source_templates/banner_warning_flashed.html @@ -1,7 +1,8 @@ {# these are flash messages that appear at the top and are really scary, like if you're using tor2web #} {% with messages = get_flashed_messages(with_categories=True, category_filter=["banner-warning"]) %} - {% for category, message in messages %} -

{{ gettext('Warning') }} - {{ message }}

- {% endfor %} -{% endwith %} +{% for category, message in messages %} + +{% endfor %} +{% endwith %} \ No newline at end of file diff --git a/securedrop/source_templates/base.html b/securedrop/source_templates/base.html index 5e60143155..921c00bdf8 100644 --- a/securedrop/source_templates/base.html +++ b/securedrop/source_templates/base.html @@ -1,55 +1,60 @@ - - - - {% if g.organization_name == "SecureDrop" %} - {{ g.organization_name }} | {{ gettext('Protecting Journalists and Sources') }} - {% else %} - {{ g.organization_name }} | {{ gettext('SecureDrop') }} - {% endif %} - - - - {% block extrahead %}{% endblock %} - - - {% include 'banner_warning_flashed.html' %} - -
-
+ + + + + {% if g.organization_name == "SecureDrop" %} + {{ g.organization_name }} | {{ gettext('Protecting Journalists and Sources') }} + {% else %} + {{ g.organization_name }} | {{ gettext('SecureDrop') }} + {% endif %} + + + + {% block extrahead %}{% endblock %} + + + + {% include 'banner_warning_flashed.html' %} + +
+
+
{% block header %} - + + + + {% include 'locales.html' %} {% endblock %} +
-
- {% if g.show_offline_message %} +
+ {% if g.show_offline_message %} +

{{ gettext("We're sorry, our SecureDrop is currently offline.") }}

{{ gettext("Please try again later. Check our website for more information.") }}

- {% else %} +
+ {% else %} - {% if 'logged_in' in session %} - {{ gettext('LOG OUT') }} - {% endif %} + {% if 'logged_in' in session %} + + {% endif %} - {% if not new_user%} -
- {% endif %} + {% endif %} - {% endif %} + {% block body %}{% endblock %} +
+
- {% block body %}{% endblock %} -
-
+ {% block footer %} + {% include 'footer.html' %} + {% endblock %} +
+ - {% block footer %} - {% include 'footer.html' %} - {% endblock %} -
- - + \ No newline at end of file diff --git a/securedrop/source_templates/error.html b/securedrop/source_templates/error.html index fa83ed90bd..5a0e6c46c8 100644 --- a/securedrop/source_templates/error.html +++ b/securedrop/source_templates/error.html @@ -5,4 +5,4 @@

{{ gettext('Server error') }}

{{ gettext('Sorry, the website encountered an error and was unable to complete your request.') }}

{{ gettext('Look up a codename...') }}

-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/securedrop/source_templates/first_submission_flashed_message.html b/securedrop/source_templates/first_submission_flashed_message.html index b2d131d355..088a07f7b4 100644 --- a/securedrop/source_templates/first_submission_flashed_message.html +++ b/securedrop/source_templates/first_submission_flashed_message.html @@ -1,8 +1,8 @@ -{{ gettext('Success') }} -
{{ gettext('Success!') }} +
+

{{ gettext('Success!') }}

{{ gettext('Thank you for sending this information to us. Please check back later for replies.') }} - - {{ gettext('Forgot your codename?') }} + + {{ gettext('Forgot your codename?') }}

-
+ \ No newline at end of file diff --git a/securedrop/source_templates/flashed.html b/securedrop/source_templates/flashed.html index b6fb74010d..ec6db8026e 100644 --- a/securedrop/source_templates/flashed.html +++ b/securedrop/source_templates/flashed.html @@ -1,18 +1,15 @@ {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} - {% for category, message in messages %} + {% endif %} -{% endwith %} +{% endwith %} \ No newline at end of file diff --git a/securedrop/source_templates/footer.html b/securedrop/source_templates/footer.html index ca7b8dda9c..a91cfe7ea9 100644 --- a/securedrop/source_templates/footer.html +++ b/securedrop/source_templates/footer.html @@ -1,12 +1,11 @@ - +

+ \ No newline at end of file diff --git a/securedrop/source_templates/generate.html b/securedrop/source_templates/generate.html index e8e771d689..2fe2e30e9f 100644 --- a/securedrop/source_templates/generate.html +++ b/securedrop/source_templates/generate.html @@ -3,35 +3,29 @@ {% block body %}

{{ gettext('Welcome') }}

- +

+ {{ gettext('Please either write this codename down and keep it in a safe place, or memorize it.') }}

-

{{ gettext('This codename is what you will use in future visits to receive messages from our team in response to what you submit on the next screen.') }}

- -
+

+ {{ gettext('This codename is what you will use in future visits to receive messages from our team in response to what you submit on the next screen.') }} +

-
- -

{{ codename }}

+
+

{{ gettext('Codename') }}

+ {{ codename }}
-
-
-
- -
- -
+ -

{{ gettext('Because we do not track users of our SecureDrop +

+ {{ gettext('Because we do not track users of our SecureDrop service, in future visits, using this codename will be the only way we have to communicate with you should we have questions or are interested in additional information. Unlike passwords, there is no way to retrieve a lost codename.') }}

@@ -39,8 +33,9 @@

{{ gettext('Welcome') }}

-
-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/securedrop/source_templates/index.html b/securedrop/source_templates/index.html index d451e33baf..363405cea1 100644 --- a/securedrop/source_templates/index.html +++ b/securedrop/source_templates/index.html @@ -1,86 +1,111 @@ - - {% if g.organization_name == "SecureDrop" %} - {{ g.organization_name }} | {{ gettext('Protecting Journalists and Sources') }} - {% else %} - {{ g.organization_name }} | {{ gettext('SecureDrop') }} - {% endif %} - - - - + + {% if g.organization_name == "SecureDrop" %} + {{ g.organization_name }} | {{ gettext('Protecting Journalists and Sources') }} + {% else %} + {{ g.organization_name }} | {{ gettext('SecureDrop') }} + {% endif %} - {% assets filters="jsmin", output="gen/source.js", "js/source.js" %} - - {% endassets %} - - -
  {{ gettext('Your Tor Browser\'s Security Level is too low. Use the "Security Level"  button in your browser’s toolbar to change it.').format(icon=url_for("static", filename="i/font-awesome/white/guard.svg")) }}
-
{{ gettext('It is recommended to use Tor Browser to access SecureDrop: Learn how to install it, or ignore this warning to continue.').format(tor_browser_url=url_for('info.recommend_tor_browser')) }} {{ gettext('Close') }}
-
{{ gettext('It is recommended you use the desktop version of Tor Browser to access SecureDrop, as Orfox does not provide the same level of security and anonymity as the desktop version. Learn how to install it, or ignore this warning to continue.').format(tor_browser_url=url_for('info.recommend_tor_browser')) }} {{ gettext('Close') }}
+ + + + - {% include 'banner_warning_flashed.html' %} + {% assets filters="jsmin", output="gen/source.js", "js/source.js" %} + + {% endassets %} + -
-
- {% include 'flashed.html' %} - {# The div `index-wrap` MUST be ordered this way so that the flexbox works on large and small screens + + + {# Warning bubble to help TB users disable JavaScript with NoScript. + Included here so the images can preload while the user is first + reading the page. Hidden by default. #} + + +
    +
  1. + {{ gettext('Click the "Security Level" button in the toolbar above').format(icon=url_for("static", filename="i/font-awesome/black/guard.svg")) }} +
  2. +
  3. {{ gettext('Select Advanced Security Settings') }}
  4. +
  5. {{ gettext('Select Safest') }}
  6. +
+

+ {{ gettext('Refresh this page, and you\'re done!') }} +

+ +
+ + + + {% include 'banner_warning_flashed.html' %} + +
+
+ {% include 'flashed.html' %} + {# The div `index-wrap` MUST be ordered this way so that the flexbox works on large and small screens See _source_index.sass for a more full understanding. #} -
-
- {{ g.organization_name }} | {{ gettext('Logo Image') }} -
- {% include 'locales.html' %} -
+
+
+

{{ gettext('{} logo'.format(g.organization_name)) }} +

+
+ {% include 'locales.html' %}
+
-
-
-
-

+
+
+
+

{{ gettext('First submission') }}

{{ gettext('First time submitting to our SecureDrop? Start here.') }}

-
-

-
-
-
-

+ + +
+
+
+

{{ gettext('Return visit') }}

-

{{ gettext('Already have a codename? Check for replies or submit something new.') }}

-
- +

+ {{ gettext('Already have a codename? Check for replies or submit something new.') }}

+

+ -
+ +
{% include 'footer.html' %}
+
- {# Warning bubble to help TB users disable JavaScript with NoScript. - Included here so the images can preload while the user is first - reading the page. Hidden by default. #} -
-
    -
  1. {{ gettext('Click the "Security Level" button in the toolbar above').format(icon=url_for("static", filename="i/font-awesome/black/guard.svg")) }}
  2. -
  3. {{ gettext('Select Advanced Security Settings') }}
  4. -
  5. {{ gettext('Select Safest') }}
  6. -
-

{{ gettext('Refresh this page, and you\'re done!') }}

-
+ - - + \ No newline at end of file diff --git a/securedrop/source_templates/locales.html b/securedrop/source_templates/locales.html index ccf8d6c07e..760bfa12aa 100644 --- a/securedrop/source_templates/locales.html +++ b/securedrop/source_templates/locales.html @@ -1,35 +1,34 @@ {% if g.locales|length > 1 %} - -{% endif %} + +{% endif %} \ No newline at end of file diff --git a/securedrop/source_templates/login.html b/securedrop/source_templates/login.html index b3a703e61c..2fd636f60f 100644 --- a/securedrop/source_templates/login.html +++ b/securedrop/source_templates/login.html @@ -6,25 +6,30 @@

{{ gettext('Enter Codename') }}

- + -

- {{ form.codename(id="login-with-existing-codename", class="codename-box", autocomplete="off", placeholder=gettext('Enter your codename'), autofocus=True) }} -
- {% for error in form.codename.errors %} - {{ error }} - {% endfor %} -

+
+ {% set aria_attributes = {'aria-label': gettext('Enter your codename'), 'aria-required': 'true'} %} + {% if form.codename.errors %} + {% set _dummy = aria_attributes.update({'aria-describedby': 'flashed login-with-existing-code-name-errors', 'aria-invalid': 'true'}) %} + {% endif %} + {{ form.codename(id='login-with-existing-codename', class='codename-box', autocomplete='off', placeholder=gettext('Enter your codename'), autofocus=True, **aria_attributes) }} + {% if form.codename.errors %} + + {% endif %} +
-
- - - - - {{ gettext('CANCEL') }} -
+
+ + + {{ gettext('CANCEL') }} +
-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/securedrop/source_templates/logout.html b/securedrop/source_templates/logout.html index a928d4597f..ae2974b9e6 100644 --- a/securedrop/source_templates/logout.html +++ b/securedrop/source_templates/logout.html @@ -1,8 +1,13 @@ {% extends "base.html" %} {% block body %} - {{ gettext('LOG IN') }} - -
+ +

{{ gettext('One more thing...') }}

-

{{ gettext('Click the  New Identity button in your Tor Browser\'s toolbar. This will clear your Tor Browser activity data on this device.').format(icon=url_for('static', filename='i/torbroom-black.png')) }}

-{% endblock %} +

+ {{ gettext('Click the  New Identity button in your Tor Browser\'s toolbar. This will clear your Tor Browser activity data on this device.').format(icon=url_for('static', filename='i/torbroom-black.png')) }} +

+
+{% endblock %} \ No newline at end of file diff --git a/securedrop/source_templates/lookup.html b/securedrop/source_templates/lookup.html index 00ae11b053..095bcb3a65 100644 --- a/securedrop/source_templates/lookup.html +++ b/securedrop/source_templates/lookup.html @@ -1,117 +1,111 @@ {% extends "base.html" %} -{% block body %} +{% block body %} {% if new_user %} -
-
- {{ gettext('Remember, your codename is:') }} - {{ gettext('Show') }} -
- {{ gettext('Hide') }} -

{{ codename }}

-
-
-
-
-{% else %} -
+
+ {{ gettext('Remember, your codename is:') }} + {{ codename }} +
{% endif %}
{% include 'flashed.html' %}
-{% if allow_document_uploads %} -

{{ gettext('Submit Files or Messages') }}

-

{{ gettext('You can submit any kind of file, a message, or both.') }}

-{% else %} -

{{ gettext('Submit Messages') }}

-{% endif %} - -

-{% if allow_document_uploads %} -{{ gettext('If you are already familiar with GPG, you can optionally encrypt your files and messages with our public key before submission. Files are encrypted as they are received by SecureDrop.').format(url=url_for('info.download_public_key')) }} -{% else %} -{{ gettext('If you are already familiar with GPG, you can optionally encrypt your messages with our public key before submission.').format(url=url_for('info.download_public_key')) }} -{% endif %} -{{ gettext('Learn more.').format(url=url_for('info.why_download_public_key')) }}

+
+ {% if allow_document_uploads %} +

{{ gettext('Submit Files or Messages') }}

+

{{ gettext('You can submit any kind of file, a message, or both.') }}

+ {% else %} +

{{ gettext('Submit Messages') }}

+ {% endif %} -
+

+ {% if allow_document_uploads %} + {{ gettext('If you are already familiar with GPG, you can optionally encrypt your files and messages with our public key before submission. Files are encrypted as they are received by SecureDrop.').format(url=url_for('info.download_public_key')) }} + {% else %} + {{ gettext('If you are already familiar with GPG, you can optionally encrypt your messages with our public key before submission.').format(url=url_for('info.download_public_key')) }} + {% endif %} + {{ gettext('Learn more.').format(url=url_for('info.why_download_public_key')) }} +

-
- -
-{% if allow_document_uploads %} -
- - {{ form.fh() }} -

{{ gettext('Maximum upload size: 500 MB') }}

-
-{% endif %} -
+ + +
+ {% if allow_document_uploads %} +
+ {{ form.fh(**{"aria-describedby": "max-file-size"}) }} +

{{ gettext('Maximum upload size: 500 MB') }}

+
+ {% endif %} +
{{ form.msg(class="fill-parent") }} +
-
-
-
- +
+ - - - - {{ gettext('CANCEL') }} - -
- - -
+ + {{ gettext('CANCEL') }} + +
+ +
-

{{ gettext('Read Replies') }}

+
+

{{ gettext('Read Replies') }}

-
- {% if replies %} - -
+
+ {% if replies %} +

+ {{ gettext("You have received a reply. To protect your identity in the unlikely event someone learns your codename, please delete all replies when you're done with them. This also lets us know that you are aware of our reply. You can respond by submitting new files and messages above.") }} +

{% for reply in replies %} -
- -
- - - - {{ gettext('Delete reply') }} - {{ gettext('Delete reply') }} - -
-

{{ gettext('Delete this reply?') }} - {{ gettext('Cancel') }} - -

-
-
-
{{ reply.decrypted | nl2br }}
-
-
+
+

+
+ + + + {{ gettext('Delete') }} + + + +

{{ gettext('Delete this reply?') }} + {{ gettext('Cancel') }} + +

+
+
+
{{ reply.decrypted | nl2br }}
+
{% endfor %}
- {{ gettext('DELETE ALL REPLIES') }} + {{ gettext('DELETE ALL REPLIES') }} -
-

{{ gettext('Are you finished with the replies?') }}

+ +

{{ gettext('Are you finished with the replies?') }}

- {{ gettext('NO, NOT YET') }} -
+ {{ gettext('NO, NOT YET') }} +
- {% else %} -

{{ gettext('— No Messages —') }}

- {% endif %} -
+ {% else %} +

{{ gettext('No Messages') }}

+ {% endif %} +
+
-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/securedrop/source_templates/next_submission_flashed_message.html b/securedrop/source_templates/next_submission_flashed_message.html index 2c68f80216..26c5acc0e9 100644 --- a/securedrop/source_templates/next_submission_flashed_message.html +++ b/securedrop/source_templates/next_submission_flashed_message.html @@ -1,4 +1,3 @@ -{{ gettext('Success') }} -
+

{{ html_contents }}

-
+ \ No newline at end of file diff --git a/securedrop/source_templates/notfound.html b/securedrop/source_templates/notfound.html index b57d3fb8de..dbb8c46adf 100644 --- a/securedrop/source_templates/notfound.html +++ b/securedrop/source_templates/notfound.html @@ -5,4 +5,4 @@

{{ gettext('Page not found') }}

{{ gettext("Sorry, we couldn't locate what you requested.") }}

{{ gettext('Look up a codename...') }}

-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/securedrop/source_templates/session_timeout.html b/securedrop/source_templates/session_timeout.html index 60377c2f87..ee1ef96f2e 100644 --- a/securedrop/source_templates/session_timeout.html +++ b/securedrop/source_templates/session_timeout.html @@ -1,6 +1,8 @@ -
- {{ gettext('Important') }} -
+

+ {{ gettext('Important') }} +

-

{{ gettext('You were logged out due to inactivity. Click the  New Identity button in your Tor Browser\'s toolbar before moving on. This will clear your Tor Browser activity data on this device.').format(icon=url_for('static', filename='i/torbroom-coral.png')) }}

-
+

+ {{ gettext('You were logged out due to inactivity. Click the  New Identity button in your Tor Browser\'s toolbar before moving on. This will clear your Tor Browser activity data on this device.').format(icon=url_for('static', filename='i/torbroom-coral.png')) }} +

+
\ No newline at end of file diff --git a/securedrop/source_templates/tor2web-warning.html b/securedrop/source_templates/tor2web-warning.html index 82aa60d66f..62f40be8cd 100644 --- a/securedrop/source_templates/tor2web-warning.html +++ b/securedrop/source_templates/tor2web-warning.html @@ -2,6 +2,8 @@ {% block body %}

{{ gettext('Why is there a warning about Tor2Web?') }}

{{ gettext('Using Tor2Web to connect to SecureDrop will not protect your anonymity.') }}

-

{{ gettext('It could be possible for anyone monitoring your Internet traffic (your government, your Internet provider), to identify you.') }}

-

{{ gettext('We strongly advise you to use the Tor Browser instead.') }}

-{% endblock %} +

{{ gettext('It could be possible for anyone monitoring your Internet traffic (your government, your Internet provider), to identify you.') }} +

+

{{ gettext('We strongly advise you to use the Tor Browser instead.') }} +

+{% endblock %} \ No newline at end of file diff --git a/securedrop/source_templates/use-tor-browser.html b/securedrop/source_templates/use-tor-browser.html index 53b9d98790..86318f0bae 100644 --- a/securedrop/source_templates/use-tor-browser.html +++ b/securedrop/source_templates/use-tor-browser.html @@ -2,9 +2,11 @@ {% block body %}

{{ gettext('You Should Use Tor Browser') }}

{{ gettext('If you are not using Tor Browser, you may not be anonymous.') }}

-

{{ gettext('If you want to submit information to SecureDrop, we strongly advise you to install Tor Browser and use it to access our site safely and anonymously.') }}

+

{{ gettext('If you want to submit information to SecureDrop, we strongly advise you to install Tor Browser and use it to access our site safely and anonymously.') }} +

{{ gettext('Copy and paste the following address into your browser and follow the instructions to download and install Tor Browser:') }} -

https://www.torproject.org/projects/torbrowser.html

-

{{ gettext('If there is a chance that downloading Tor Browser raises suspicion and your mail provider is less likely to be monitored, you can send a mail to

gettor@torproject.org
and a bot will answer with instructions.') }}

-{% endblock %} +
https://www.torproject.org/projects/torbrowser.html
+

{{ gettext('If there is a chance that downloading Tor Browser raises suspicion and your mail provider is less likely to be monitored, you can send a mail to gettor@torproject.org and a bot will answer with instructions.') }} +

+{% endblock %} \ No newline at end of file diff --git a/securedrop/source_templates/why-public-key.html b/securedrop/source_templates/why-public-key.html index 3aa1dc65d1..ce19128c72 100644 --- a/securedrop/source_templates/why-public-key.html +++ b/securedrop/source_templates/why-public-key.html @@ -1,27 +1,33 @@ {% extends "base.html" %} {% block body %}

{{ gettext("Why download the team's public key?") }}

-

{{ gettext("SecureDrop encrypts files and messages after they are submitted. Encrypting messages and files before submission can provide an extra layer of security before your data reaches the SecureDrop server.") }}

+

{{ gettext("SecureDrop encrypts files and messages after they are submitted. Encrypting messages and files before submission can provide an extra layer of security before your data reaches the SecureDrop server.") }} +

{{ gettext("If you are already familiar with the GPG encryption software, you may wish to encrypt your submissions yourself. To do so:") }}

  1. {{ gettext('Download the public key. It will be saved to a file called: -

    {submission_key_fpr_filename}

    ').format(url=url_for('info.download_public_key'), submission_key_fpr_filename=submission_key_fpr + '.asc')|safe }}
  2. -
  3. {{ gettext('Import it into your GPG keyring.') }} -
      -
    • {{ gettext('If you are using Tails, you can double-click the .asc file you just downloaded and it will be automatically imported to your keyring.').format(url='https://tails.boum.org') }}
    • -
    • {{ gettext('If you are using macOS or Linux, open the terminal. You can import the key with:

      gpg --import /path/to/{submission_key_fpr_filename}

      ').format(url_for('info.download_public_key'), submission_key_fpr_filename=submission_key_fpr + '.asc')|safe }}
    • -
    -
  4. -
  5. {{ gettext('Encrypt your submission. Open the terminal and enter this gpg command:') }} -

    {{ gettext('gpg --recipient \'{submission_key_fpr}\' --encrypt /path/to/submission').format(submission_key_fpr=submission_key_fpr)|safe }}

    -
  6. -
  7. {{ gettext('Upload your encrypted submission. It will have the same filename as the unencrypted file, with .gpg at the end (e.g. internal_memo.pdf.gpg)') }}
  8. +

    {submission_key_fpr_filename}

    ').format(url=url_for('info.download_public_key'), submission_key_fpr_filename=submission_key_fpr + '.asc')|safe }} + +
  9. {{ gettext('Import it into your GPG keyring.') }} +
      +
    • {{ gettext('If you are using Tails, you can double-click the .asc file you just downloaded and it will be automatically imported to your keyring.').format(url='https://tails.boum.org') }} +
    • +
    • {{ gettext('If you are using macOS or Linux, open the terminal. You can import the key with:

      gpg --import /path/to/{submission_key_fpr_filename}

      ').format(url_for('info.download_public_key'), submission_key_fpr_filename=submission_key_fpr + '.asc')|safe }} +
    • +
    +
  10. +
  11. {{ gettext('Encrypt your submission. Open the terminal and enter this gpg command:') }} +

    {{ gettext('gpg --recipient \'{submission_key_fpr}\' --encrypt /path/to/submission').format(submission_key_fpr=submission_key_fpr)|safe }} +

    +
  12. +
  13. {{ gettext('Upload your encrypted submission. It will have the same filename as the unencrypted file, with .gpg at the end (e.g. internal_memo.pdf.gpg)') }} +
-

{{ gettext('Important: If you wish to remain anonymous, do not use GPG to sign the encrypted file (with the --sign or -s flag) as this will reveal your GPG identity to us.')|safe }}

+

{{ gettext('Important: If you wish to remain anonymous, do not use GPG to sign the encrypted file (with the --sign or -s flag) as this will reveal your GPG identity to us.')|safe }} +

- - {{ gettext('Back to submission page') }} + {{ gettext('Back to submission page') }}

-{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/securedrop/tests/functional/source_navigation_steps.py b/securedrop/tests/functional/source_navigation_steps.py index 9856541214..ebf33bd6db 100644 --- a/securedrop/tests/functional/source_navigation_steps.py +++ b/securedrop/tests/functional/source_navigation_steps.py @@ -58,25 +58,27 @@ def _source_chooses_to_submit_documents(self): self.source_name = codename.text def _source_shows_codename(self, verify_source_name=True): - content = self.driver.find_element_by_id("codename-hint-content") - assert not content.is_displayed() + # The DETAILS element will be missing the OPEN attribute if it is + # closed, hiding its contents. + content = self.driver.find_element_by_css_selector("details#codename-hint") + assert content.get_attribute("open") is None - self.safe_click_by_id("codename-hint-show") + self.safe_click_by_id("codename-hint") - self.wait_for(lambda: content.is_displayed()) - assert content.is_displayed() - content_content = self.driver.find_element_by_css_selector("#codename-hint-content p") + assert content.get_attribute("open") is not None + content_content = self.driver.find_element_by_css_selector("details#codename-hint mark") if verify_source_name: assert content_content.text == self.source_name def _source_hides_codename(self): - content = self.driver.find_element_by_id("codename-hint-content") - assert content.is_displayed() + # The DETAILS element will have the OPEN attribute if it is open, + # displaying its contents. + content = self.driver.find_element_by_css_selector("details#codename-hint") + assert content.get_attribute("open") is not None - self.safe_click_by_id("codename-hint-hide") + self.safe_click_by_id("codename-hint") - self.wait_for(lambda: not content.is_displayed()) - assert not content.is_displayed() + assert content.get_attribute("open") is None def _source_sees_no_codename(self): codename = self.driver.find_elements_by_css_selector(".code-reminder") diff --git a/securedrop/tests/functional/test_source.py b/securedrop/tests/functional/test_source.py index 65ac9737db..276924c9b5 100644 --- a/securedrop/tests/functional/test_source.py +++ b/securedrop/tests/functional/test_source.py @@ -65,7 +65,7 @@ def get_codename_generate(self): return self.driver.find_element_by_css_selector("#codename").text def get_codename_lookup(self): - return self.driver.find_element_by_css_selector("#codename-hint-content p").text + return self.driver.find_element_by_css_selector("#codename-hint mark").text def test_duplicate_generate_pages(self): # Test generation of multiple codenames in different browser tabs, ref. issue 4458. diff --git a/securedrop/tests/test_source.py b/securedrop/tests/test_source.py index b601a9c083..588535067d 100644 --- a/securedrop/tests/test_source.py +++ b/securedrop/tests/test_source.py @@ -101,8 +101,8 @@ def _find_codename(html): """Find a source codename (diceware passphrase) in HTML""" # Codenames may contain HTML escape characters, and the wordlist # contains various symbols. - codename_re = (r'

]*id="codename"[^>]*>' - r'(?P[a-z0-9 &#;?:=@_.*+()\'"$%!-]+)

') + codename_re = (r']*id="codename"[^>]*>' + r'(?P[a-z0-9 &#;?:=@_.*+()\'"$%!-]+)') codename_match = re.search(codename_re, html) assert codename_match is not None return codename_match.group('codename')