Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cosign improvements - batch 1 #4808

Merged
merged 14 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions docs/configuration/general/cosign.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
.. _configuration_general_cosign:

=========
Cosigning
=========

Open Forms supports form submission flows where a second person needs to cosign the
submission before it gets processed.

Roughly summarized there are two variations for the cosigner:

* the cosign request email contains a link taking the cosigner directly to the right
page
* the cosign request does not contain a link, but instead it instructs the user how
to start the cosign process

The global configuration influences which variation is used.

.. tip::

Read :ref:`the manual (Dutch) <manual_cosign_flow>` to learn more about the flow
and how to enable this in a form.


Confirmation page configuration
===============================

When the form submitter completes the submission, they get a confirmation page of the
submitted data. The content of this page is configurable. Navigate to **Admin** >
**Configuratie** > **Algemene configuratie**, section
**Formulieren met mede-ondertekenen**:

**Titel mede-ondertekenenbevestigingspagina**
The main page title displayed for the confirmation page. You can use the template
variable ``{{ public_reference }}`` here.

**Mede-ondertekenenbevestigingspagina tekst**
The body text of the confirmation page. This WYSIWYG content supports some template
expressions too:

* ``{{ public_reference }}``: the reference number in case the user needs to contact
your organization. Strongly recommended to include this somewhere.
* ``{{ cosigner_email }}``: the email address that will receive the cosign request
email.
* ``{% cosign_button text="Nu ondertekenen" %}``: a button to start the cosign
process immediately from the confirmation page. You can provide the button text
as an argument.

Both Dutch and English variants can be configured to support multi-language forms.

Cosign request email configuration
==================================

The person that needs to cosign the submission will receive an email requesting them to
do this. The content of this email is configurable. Navigate to **Admin** >
**Configuratie** > **Algemene configuratie**, section
**Mede-ondertekenen e-mails**:

**Mede-ondertekenenverzoeksjabloon**
The content of the cosign request email. This is a template that supports a number
of expressions:

* ``{{ form_name }}``: the name/title of the form that requires cosigning
* ``{{ form_url }}``: a deep link to start the cosign process. If this variable is
present, the cosign login options are not displayed on the regular form start
page and the cosigner does not have to enter the code, otherwise both regular and
cosign login options are displayed. If you omit this link (e.g. for security
reasons), you should provide clear instructions how the cosigner can find the
form on your website(s).
* ``{{ code }}``: the cosign submission code. This code needs to be provided to
retrieve the submission that needs to be cosigned. If you use deep links, you can
omit this, as the code is already included in the link.
1 change: 1 addition & 0 deletions docs/configuration/general/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ General configuration
cms_integration
virus_scan
payment_flow
cosign
77 changes: 56 additions & 21 deletions docs/manual/forms/cosign_flow.rst
Original file line number Diff line number Diff line change
@@ -1,35 +1,70 @@
.. _manual_cosign_flow:

=================
Mede-ondertekenen
=================

Open Formulieren ondersteunt formulieren waarin een tweede persoon een inzending moet ondertekenen voor deze
verwerkt wordt, zoals een partner of voogd. Er is dus een extra persoon betrokken naast de invuller van het formulier.
Open Formulieren ondersteunt formulieren waarin een tweede persoon een inzending moet
ondertekenen voor deze verwerkt wordt, zoals een partner of voogd. Er is dus een extra
persoon betrokken naast de invuller van het formulier.

Flow
----
Het mede-ondertekenproces kent twee varianten, afhankelijk van de precieze
:ref:`algemene configuratie <configuration_general_cosign>` ingesteld door een
beheerder. Voor beide varianten dien je een "mede-onderteken"-component in het
formulier toe te voegen om mede-ondertekenen te activeren.

De mede-ondertekenen flow is hieronder beschreven. Persoon 1 is de persoon die als eerste het formulier invult.
Persoon 2 is de mede-ondertekenaar.
We beschrijven twee persona:

#. Persoon 1 logt in om het formulier te beginnen.
#. In het formulier bevindt zich een "Mede-ondertekenen" component. Hier kan persoon 1 het e-mailadres van persoon 2
opgeven.
#. Zodra het formulier ingestuurd wordt, krijgt persoon 1 een bevestigingsmail (als deze ingeschakeld is).
#. Persoon 2 ontvangt een e-mail met het verzoek om het formulier te mede-ondertekenen. De e-mail
bevat of een directe link óf instructies om het formulier te openen (afhankelijk van de instelling in de
**Algemene configuratie**). In de e-mail staat een verificatiecode voor de inzending.
#. Persoon 2 navigeert naar de startpagina van het formulier en logt in met de
**Log in om het formulier mede te ondertekenen**-knop.
* de klant: de persoon die het formulier initieel start en invult
* de ondertekenaar: de persoon die de inzending mede moet ondertekenen

Met links in emails
===================

#. De klant navigeert naar het formulier, waar de inlogopties zoals gebruikelijk
zichtbaar zijn. Er zijn geen "mede-ondertekeneninlogopties".
#. De klant logt in en vult het formulier in.
#. Bij het "mede-onderteken"-component vult de klant het e-mailadres van de
ondertekenaar in.
#. Zodra het formulier ingestuurd wordt, worden e-mails verstuurd:

* de klant krijgt een bevestigingsmail (als deze inschakeld is)
* de ondertekenaar krijgt een e-mail met het ondertekenverzoek, waarin de
formulierlink staat

#. De ondertekenaar klikt op de link in de email en krijgt een startscherm met uitleg
over het mede-ondertekenen.
#. De ondertekenaar logt in en ziet vervolgens een overzicht van de ingevulde gegevens.
Indien relevant accepteert die de verklaring van waarheid en/of privacybeleid. Daarna
bevestigt die de mede-ondertekening.
#. De klant en de ondertekenaar ontvangen allebei een bevestigingsmail.
#. De inzending wordt nu verwerkt met de gekoppelde registratieplugin (dus pas ná het
mede-ondertekenen).

Zonder links in emails
======================

#. De klant navigeert naar het formulier, waar de inlogopties zoals gebruikelijk
zichtbaar zijn, aangevuld met de "mede-ondertekeneninlogopties".

.. image:: _assets/cosign_buttons.png
:width: 100%

#. Vervolgens moet persoon 2 de verificatiecode uit de e-mail invullen. Bij een geldige code ziet de gebruiker een
overzicht van de ingevulde gegevens.
#. Indien relevant, dan moet persoon 2 het privacybeleid en/of de verklaring van waarheid accepteren (dit is een
formulierinstelling). Daarna bevestigt de gebruiker de mede-ondertekening.
#. Persoon 1 en persoon 2 ontvangen daarna allebei een bevestigingsmail.
#. De inzending wordt nu verwerkt met de gekoppelde registratieplugin (dus pas ná het mede-ondertekenen).
#. De klant logt in en vult het formulier in.
#. Bij het "mede-onderteken"-component vult de klant het e-mailadres van de
ondertekenaar in.
#. Zodra het formulier ingestuurd wordt, worden e-mails verstuurd:

* de klant krijgt een bevestigingsmail (als deze inschakeld is)
* de ondertekenaar krijgt een e-mail met het ondertekenverzoek, met instructies om
het formulier te openen. In de e-mail staat een verificatiecode voor de inzending.

#. De ondertekenaar navigeert naar de startpagina van het formulier en logt in met de
**Log in om het formulier mede te ondertekenen**-knop.
#. Vervolgens moet de ondertekenaar de verificatiecode uit de e-mail invullen. Bij een
geldige code ziet de gebruiker een overzicht van de ingevulde gegevens.
#. Indien relevant accepteert de ondertekenaar de verklaring van waarheid
en/of privacybeleid. Daarna bevestigt die de mede-ondertekening.
#. De klant en de ondertekenaar ontvangen allebei een bevestigingsmail.
#. De inzending wordt nu verwerkt met de gekoppelde registratieplugin (dus pas ná het
mede-ondertekenen).
17 changes: 9 additions & 8 deletions src/csp_post_processor/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"th",
"td",
"hr",
"button",
# NOTE we don't add "style" here
]

Expand Down Expand Up @@ -84,17 +85,17 @@
"figure": ["title", "src"],
# CKEditor has a table designer with spans
"td": ["colspan", "rowspan"],
# Button class for NL DS styling + type
"button": ["class", "type"],
}

wysiwyg_css_properties = list(css_sanitizer.ALLOWED_CSS_PROPERTIES)
wysiwyg_css_properties.append(
[
# TinyMCE uses padding-left for indent
"padding-left",
# TinyMCE uses list-style-type for list styling
"list-style-type",
]
)
wysiwyg_css_properties += [
# TinyMCE uses padding-left for indent
"padding-left",
# TinyMCE uses list-style-type for list styling
"list-style-type",
]

wysiwyg_svg_properties = list(css_sanitizer.ALLOWED_SVG_PROPERTIES)

Expand Down
16 changes: 16 additions & 0 deletions src/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7788,6 +7788,12 @@ components:
items:
$ref: '#/components/schemas/LoginOption'
readOnly: true
cosignHasLinkInEmail:
type: boolean
readOnly: true
title: cosign request has links in email
description: Indicates whether deep links are included in the cosign request
emails or not.
cosignLoginInfo:
allOf:
- $ref: '#/components/schemas/CosignLoginInfo'
Expand Down Expand Up @@ -7829,6 +7835,7 @@ components:
- $ref: '#/components/schemas/BRPPersonenRequestOptions'
nullable: true
required:
- cosignHasLinkInEmail
- cosignLoginInfo
- cosignLoginOptions
- hideNonApplicableSteps
Expand Down Expand Up @@ -9454,6 +9461,12 @@ components:
items:
$ref: '#/components/schemas/LoginOption'
readOnly: true
cosignHasLinkInEmail:
type: boolean
readOnly: true
title: cosign request has links in email
description: Indicates whether deep links are included in the cosign request
emails or not.
cosignLoginInfo:
allOf:
- $ref: '#/components/schemas/CosignLoginInfo'
Expand Down Expand Up @@ -10113,6 +10126,9 @@ components:
description: The public registration reference, sourced from the registration
backend or otherwise uniquely generated in case the backend could not
provide it.
confirmationPageTitle:
type: string
description: Title of the confirmation page.
confirmationPageContent:
type: string
description: Body text of the confirmation page. May contain HTML!
Expand Down
7 changes: 4 additions & 3 deletions src/openforms/authentication/api/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from openforms.authentication.api.serializers import LoginOptionSerializer
from openforms.authentication.registry import register as auth_register
from openforms.forms.models import Form


class LoginOptionsReadOnlyField(serializers.ListField):
Expand All @@ -24,7 +25,7 @@ def __init__(self, is_for_cosign: bool = False, *args, **kwargs) -> None:
def to_internal_value(self, data):
raise NotImplementedError("read only")

def to_representation(self, form):
def to_representation(self, value: Form): # type: ignore reportIncompatibleOverride
request: Request = self.context["request"]
temp = auth_register.get_options(request, form, self.is_for_cosign)
return super().to_representation(temp)
options = auth_register.get_options(request, value, self.is_for_cosign)
return super().to_representation(options)
Loading
Loading