mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-10 01:55:41 -04:00
Add confirm loop
For pages where - we want you to be sure that you want to do what you’re about to do - we want to be sure it’s you trying to do the thing This adds a page that asks the user to confirm their password.
This commit is contained in:
@@ -20,7 +20,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&-hint {
|
&-hint {
|
||||||
@include core-16;
|
@include core-19;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,8 @@
|
|||||||
.button {}
|
.button {}
|
||||||
|
|
||||||
.button-destructive {
|
.button-destructive {
|
||||||
@include button($error-colour)
|
@include button($error-colour);
|
||||||
|
padding: 0.52632em 0.78947em 0.26316em 0.78947em;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
from flask import render_template, redirect, request, url_for
|
from flask import render_template, redirect, request, url_for, abort
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
from app.main import main
|
from app.main import main
|
||||||
@@ -25,6 +25,18 @@ def name():
|
|||||||
'views/service-settings/name.html',
|
'views/service-settings/name.html',
|
||||||
service=service
|
service=service
|
||||||
)
|
)
|
||||||
|
elif request.method == 'POST':
|
||||||
|
return redirect(url_for('.confirm_name_change'))
|
||||||
|
|
||||||
|
|
||||||
|
@main.route("/service-settings/name/confirm", methods=['GET', 'POST'])
|
||||||
|
def confirm_name_change():
|
||||||
|
if request.method == 'GET':
|
||||||
|
return render_template(
|
||||||
|
'views/service-settings/confirm.html',
|
||||||
|
heading='Rename service',
|
||||||
|
submit_button_text='Confirm'
|
||||||
|
)
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST':
|
||||||
return redirect(url_for('.service_settings'))
|
return redirect(url_for('.service_settings'))
|
||||||
|
|
||||||
@@ -47,6 +59,19 @@ def status():
|
|||||||
'views/service-settings/status.html',
|
'views/service-settings/status.html',
|
||||||
service=service
|
service=service
|
||||||
)
|
)
|
||||||
|
elif request.method == 'POST':
|
||||||
|
return redirect(url_for('.confirm_status_change'))
|
||||||
|
|
||||||
|
|
||||||
|
@main.route("/service-settings/status/confirm", methods=['GET', 'POST'])
|
||||||
|
def confirm_status_change():
|
||||||
|
if request.method == 'GET':
|
||||||
|
return render_template(
|
||||||
|
'views/service-settings/confirm.html',
|
||||||
|
heading='Turn off outgoing messages',
|
||||||
|
submit_button_text='Confirm',
|
||||||
|
destructive=True
|
||||||
|
)
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST':
|
||||||
return redirect(url_for('.service_settings'))
|
return redirect(url_for('.service_settings'))
|
||||||
|
|
||||||
@@ -59,4 +84,17 @@ def delete():
|
|||||||
service=service
|
service=service
|
||||||
)
|
)
|
||||||
elif request.method == 'POST':
|
elif request.method == 'POST':
|
||||||
return redirect(url_for('.index'))
|
return redirect(url_for('.confirm_delete'))
|
||||||
|
|
||||||
|
|
||||||
|
@main.route("/service-settings/delete/confirm", methods=['GET', 'POST'])
|
||||||
|
def confirm_delete():
|
||||||
|
if request.method == 'GET':
|
||||||
|
return render_template(
|
||||||
|
'views/service-settings/confirm.html',
|
||||||
|
heading='Delete service',
|
||||||
|
submit_button_text='Confirm',
|
||||||
|
destructive=True
|
||||||
|
)
|
||||||
|
elif request.method == 'POST':
|
||||||
|
return redirect(url_for('.dashboard'))
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
{% macro list(items) %}
|
|
||||||
{% if items %}
|
|
||||||
<ul class="list list-bullet">
|
|
||||||
{% for item in items %}
|
|
||||||
<li>
|
|
||||||
{{ item }}
|
|
||||||
</li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
{% endif %}
|
|
||||||
{% endmacro %}
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
{% macro textbox(name, label, value='', small=True, highlight_tags=False) %}
|
{% macro textbox(name, label, value='', small=True, highlight_tags=False, password=False) %}
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="form-label" for="{{ name }}">{{ label }}</label>
|
<label class="form-label" for="{{ name }}">{{ label }}</label>
|
||||||
{% if small %}
|
{% if small %}
|
||||||
<input class="form-control" id="{{ name }}" name="{{ name }}" type="text" value="{{ value }}">
|
<input class="form-control" id="{{ name }}" name="{{ name }}" type="{{ 'password' if password else 'text' }}" value="{{ value }}">
|
||||||
{% else %}
|
{% else %}
|
||||||
<textarea
|
<textarea
|
||||||
class="form-control {% if highlight_tags %}textbox-highlight-textbox{% endif %}"
|
class="form-control {% if highlight_tags %}textbox-highlight-textbox{% endif %}"
|
||||||
|
|||||||
@@ -2,38 +2,38 @@
|
|||||||
{% from "components/browse-list.html" import browse_list %}
|
{% from "components/browse-list.html" import browse_list %}
|
||||||
|
|
||||||
{% block page_title %}
|
{% block page_title %}
|
||||||
GOV.UK Notify | Service settings
|
GOV.UK Notify | Service settings
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
<h1 class="heading-xlarge">Service settings</h1>
|
<h1 class="heading-xlarge">Service settings</h1>
|
||||||
|
|
||||||
{{ browse_list([
|
{{ browse_list([
|
||||||
{
|
{
|
||||||
'title': 'Rename service',
|
'title': 'Rename service',
|
||||||
'link': url_for('.name'),
|
'link': url_for('.name'),
|
||||||
'hint': 'Your service is named “{}”'.format(service.name)
|
'hint': 'Your service is called ‘{}’'.format(service.name)
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'title': 'Make service live',
|
'title': 'Request to make service live',
|
||||||
'link': url_for('.request_to_go_live'),
|
'link': url_for('.request_to_go_live'),
|
||||||
'hint': 'A live service can send messages to anyone',
|
'hint': 'A live service can send messages to any phone number or email address',
|
||||||
} if not service.live else {
|
} if not service.live else {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'title': 'Stop sending messages',
|
'title': 'Turn off outgoing messages',
|
||||||
'link': url_for('.status')
|
'link': url_for('.status'),
|
||||||
} if service.active else {
|
'destructive': True
|
||||||
'title': 'Unsuspend service',
|
} if service.active else {
|
||||||
'link': url_for('.status')
|
'title': 'Desuspend service',
|
||||||
},
|
'link': url_for('.status')
|
||||||
{
|
},
|
||||||
'title': 'Delete everything',
|
{
|
||||||
'link': url_for('.delete'),
|
'title': 'Delete service',
|
||||||
'hint': '',
|
'link': url_for('.delete'),
|
||||||
'destructive': True
|
'destructive': True
|
||||||
},
|
},
|
||||||
]) }}
|
]) }}
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
27
app/templates/views/service-settings/confirm.html
Normal file
27
app/templates/views/service-settings/confirm.html
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{% extends "withnav_template.html" %}
|
||||||
|
{% from "components/textbox.html" import textbox %}
|
||||||
|
{% from "components/submit-form.html" import submit_form %}
|
||||||
|
|
||||||
|
{% block page_title %}
|
||||||
|
GOV.UK Notify | Service settings
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
|
<h1 class="heading-xlarge">{{ heading }}</h1>
|
||||||
|
|
||||||
|
<div class="grid-row">
|
||||||
|
<div class="column-three-quarters">
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
{{ textbox('new_name', 'Enter your password', password=True) }}
|
||||||
|
{{ submit_form(
|
||||||
|
submit_button_text,
|
||||||
|
destructive=destructive,
|
||||||
|
back_link=url_for('.service_settings')
|
||||||
|
) }}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
@@ -7,16 +7,37 @@
|
|||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
<h1 class="heading-xlarge">Delete this service</h1>
|
<div class="grid-row">
|
||||||
|
<div class="column-three-quarters">
|
||||||
|
<h1 class="heading-xlarge">Delete service</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
All will be lost.
|
This can’t be undone. You will lose:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form method="post">
|
<ul class="list list-bullet">
|
||||||
{{ submit_form('Delete', destructive=True) }}
|
<li>
|
||||||
</form>
|
any data you’ve uploaded messages
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
any templates you’ve created
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
the history of
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
API keys
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
<p><a href="{{ url_for('.service_settings') }}">Back to service settings</a></p>
|
<form method="post">
|
||||||
|
{{ submit_form(
|
||||||
|
'Yes, delete ‘{}’'.format(service.name),
|
||||||
|
destructive=True,
|
||||||
|
back_link=url_for('.service_settings')
|
||||||
|
) }}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -8,15 +8,23 @@ GOV.UK Notify | Service settings
|
|||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
<h1 class="heading-xlarge">Rename your service</h1>
|
<div class="grid-row">
|
||||||
|
<div class="column-three-quarters">
|
||||||
|
|
||||||
<form method="post">
|
<h1 class="heading-xlarge">Rename service</h1>
|
||||||
{{ textbox('new_name', 'New name', value=service.name) }}
|
|
||||||
{{ submit_form('Save') }}
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<p><a href="{{ url_for('.service_settings') }}">Back to service settings</a></p>
|
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Users will see this name where?
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form method="post">
|
||||||
|
{{ textbox('new_name', 'New name', value=service.name) }}
|
||||||
|
{{ submit_form(
|
||||||
|
'Save',
|
||||||
|
back_link=url_for('.service_settings')
|
||||||
|
) }}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
{% extends "withnav_template.html" %}
|
{% extends "withnav_template.html" %}
|
||||||
{% from "components/submit-form.html" import submit_form %}
|
{% from "components/submit-form.html" import submit_form %}
|
||||||
{% from "components/list.html" import list %}
|
|
||||||
|
|
||||||
{% block page_title %}
|
{% block page_title %}
|
||||||
GOV.UK Notify | Service settings
|
GOV.UK Notify | Service settings
|
||||||
@@ -8,26 +7,42 @@ GOV.UK Notify | Service settings
|
|||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
<h1 class="heading-xlarge">Make your service live</h1>
|
<h1 class="heading-xlarge">Request to make service live</h1>
|
||||||
|
|
||||||
<div class="grid-row">
|
<div class="grid-row">
|
||||||
<div class="column-two-thirds">
|
<div class="column-three-quarters">
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Before you can send messages to anyone, you need to:
|
A live service can send messages to any phone number or email address.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{{ list([
|
<p>
|
||||||
"Have spoken to someone",
|
First you need to:
|
||||||
"Have permission from someone else",
|
</p>
|
||||||
"etc."
|
|
||||||
]) }}
|
<ul class="list list-bullet">
|
||||||
|
<li>
|
||||||
|
have spoken to someone
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
have permission from someone else
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
etc.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
It takes a few working days for your request to be approved.
|
||||||
|
</p>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{{ submit_form("Request to go live") }}
|
{{ submit_form(
|
||||||
|
'Request to make service live',
|
||||||
|
back_link=url_for('.service_settings')
|
||||||
|
) }}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<p><a href="{{ url_for('.service_settings') }}">Back to service settings</a></p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -7,24 +7,28 @@ GOV.UK Notify | Service settings
|
|||||||
|
|
||||||
{% block maincolumn_content %}
|
{% block maincolumn_content %}
|
||||||
|
|
||||||
|
<h1 class="heading-xlarge">Turn off outgoing messages</h1>
|
||||||
|
|
||||||
<div class="grid-row">
|
<div class="grid-row">
|
||||||
<div class="column-two-thirds">
|
<div class="column-three-quarters">
|
||||||
<h1 class="heading-xlarge">Suspend your service</h1>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Suspending a service means it won’t send messages. Any messages that are
|
You’ll still be able to send messages to yourself by uploading a CSV
|
||||||
already queued will still be sent.
|
file.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
You can undo this at any time.
|
You can start sending messages again when you’re ready.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{{ submit_form('Suspend') }}
|
{{ submit_form(
|
||||||
|
'Turn off outgoing messages',
|
||||||
|
destructive=True,
|
||||||
|
back_link=url_for('.service_settings')
|
||||||
|
) }}
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<p><a href="{{ url_for('.service_settings') }}">Back to service settings</a></p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ def test_should_show_service_name(notifications_admin):
|
|||||||
response = notifications_admin.test_client().get('/service-settings/name')
|
response = notifications_admin.test_client().get('/service-settings/name')
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert 'Service name' in response.get_data(as_text=True)
|
assert 'Rename service' in response.get_data(as_text=True)
|
||||||
|
|
||||||
|
|
||||||
def test_should_redirect_after_change_service_name(notifications_admin):
|
def test_should_redirect_after_change_service_name(notifications_admin):
|
||||||
@@ -19,11 +19,25 @@ def test_should_redirect_after_change_service_name(notifications_admin):
|
|||||||
assert 'http://localhost/service-settings' == response.location
|
assert 'http://localhost/service-settings' == response.location
|
||||||
|
|
||||||
|
|
||||||
|
def test_should_show_service_name_confirmation(notifications_admin):
|
||||||
|
response = notifications_admin.test_client().get('/service-settings/name/confirm')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert 'Rename service' in response.get_data(as_text=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_should_redirect_after_service_name_confirmation(notifications_admin):
|
||||||
|
response = notifications_admin.test_client().post('/service-settings/name/confirm')
|
||||||
|
|
||||||
|
assert response.status_code == 302
|
||||||
|
assert 'http://localhost/service-settings' == response.location
|
||||||
|
|
||||||
|
|
||||||
def test_should_show_request_to_go_live(notifications_admin):
|
def test_should_show_request_to_go_live(notifications_admin):
|
||||||
response = notifications_admin.test_client().get('/service-settings/request-to-go-live')
|
response = notifications_admin.test_client().get('/service-settings/request-to-go-live')
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert 'Request to go live' in response.get_data(as_text=True)
|
assert 'Request to make service live' in response.get_data(as_text=True)
|
||||||
|
|
||||||
|
|
||||||
def test_should_redirect_after_request_to_go_live(notifications_admin):
|
def test_should_redirect_after_request_to_go_live(notifications_admin):
|
||||||
@@ -37,12 +51,26 @@ def test_should_show_status_page(notifications_admin):
|
|||||||
response = notifications_admin.test_client().get('/service-settings/status')
|
response = notifications_admin.test_client().get('/service-settings/status')
|
||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert 'Suspend your service' in response.get_data(as_text=True)
|
assert 'Turn off outgoing messages' in response.get_data(as_text=True)
|
||||||
|
|
||||||
|
|
||||||
def test_should_show_redirect_after_status_change(notifications_admin):
|
def test_should_show_redirect_after_status_change(notifications_admin):
|
||||||
response = notifications_admin.test_client().post('/service-settings/status')
|
response = notifications_admin.test_client().post('/service-settings/status')
|
||||||
|
|
||||||
|
assert response.status_code == 302
|
||||||
|
assert 'http://localhost/service-settings/status/confirm' == response.location
|
||||||
|
|
||||||
|
|
||||||
|
def test_should_show_status_confirmation(notifications_admin):
|
||||||
|
response = notifications_admin.test_client().get('/service-settings/status/confirm')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert 'Turn off outgoing messages' in response.get_data(as_text=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_should_redirect_after_status_confirmation(notifications_admin):
|
||||||
|
response = notifications_admin.test_client().post('/service-settings/status/confirm')
|
||||||
|
|
||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
assert 'http://localhost/service-settings' == response.location
|
assert 'http://localhost/service-settings' == response.location
|
||||||
|
|
||||||
@@ -58,4 +86,18 @@ def test_should_show_redirect_after_deleting_service(notifications_admin):
|
|||||||
response = notifications_admin.test_client().post('/service-settings/delete')
|
response = notifications_admin.test_client().post('/service-settings/delete')
|
||||||
|
|
||||||
assert response.status_code == 302
|
assert response.status_code == 302
|
||||||
assert 'http://localhost/' == response.location
|
assert 'http://localhost/service-settings/delete/confirm' == response.location
|
||||||
|
|
||||||
|
|
||||||
|
def test_should_show_delete_confirmation(notifications_admin):
|
||||||
|
response = notifications_admin.test_client().get('/service-settings/delete/confirm')
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert 'Delete service' in response.get_data(as_text=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_should_redirect_delete_confirmation(notifications_admin):
|
||||||
|
response = notifications_admin.test_client().post('/service-settings/delete/confirm')
|
||||||
|
|
||||||
|
assert response.status_code == 302
|
||||||
|
assert 'http://localhost/dashboard' == response.location
|
||||||
|
|||||||
Reference in New Issue
Block a user