mod_signup

This module presents an interface for letting users register themselves.

Signup flow

There are three ways to start a signup:

  • Visit the public signup dispatch rule directly.

  • Ask the notification system for a #signup_url{}. This is used by modules

    that already know some user properties or identities and want to continue on the normal signup page.
  • Notify #signup{} directly. This is typically used after an external

    Zotonic user without rendering the email signup form. authentication service has identified a visitor and the site wants to create a

The #signup_url{} flow stores the caller supplied props and signup_props in mod_server_storage. The key is a generated check id and the generated URL contains that id as the xs query argument. The stored value is {CheckId, Timestamp, Props, SignupProps} so the signup controller can verify that the looked-up value belongs to the supplied xs and reject expired payloads. The stored payload is accepted for one hour after it was generated; after that the signup page falls back to a normal empty signup and deletes the expired server-storage entry.

props are resource properties for the person resource that will become the user, for example email, name_first, name_surname, or depiction_url. signup_props are signup control values and identities, for example {user_id, Id} to update an existing person, {ready_page, Url} for the post-signup redirect, or {identity, {Type, Key, IsUnique, IsVerified}}.

When controller_signup renders the page it consumes xs, fetches the stored payload, checks the stored timestamp, and passes the accepted values to the templates as props, signup_props, and optionally email. The templates include these values in the wired postbacks so the staged email signup can continue with the same prefilled data. If xs is missing, empty, unknown, expired, or points to a different check id, the signup page falls back to a normal empty signup.

The public email signup is staged:

  1. The visitor enters or confirms an email address. The controller checks for

    existing accounts, blocked addresses, rate limits, and external providers.
  2. For a new local account, a short one-time code is stored in the

    mod_signup gen_server under {signup, EmailNorm} and mailed with email_signup_code.tpl.
  3. The visitor enters the code. A valid code is deleted and the final account

    details form is rendered.
  4. The final form posts resource fields and signup identities. The controller

    model for the browser redirect. new user on, and sends a one-time authentication token to the client auth rechecks username and email uniqueness, calls signup_existing/5, logs the

The lower level #signup{} notification and signup/4 API skip the staged email-code controller flow. They still run the signup preflight checks, insert or update the user resource, add identities, emit #signup_done{}, and either confirm the signup immediately or leave the account unpublished and unverified so identity verification can be requested through #identity_verification{}.

Controllers

controller_signup renders signup.tpl and handles the browser postbacks for the email signup flow. It owns the short email-code confirmation, prefilled xs payload handling, final form validation, signup execution, logon, and client-side redirect token. The page itself includes _signup_box.tpl; other pages can include _signup_box.tpl directly to show the same signup UI without using the public signup page template.

controller_signup_confirm renders signup_confirm.tpl and handles account identity confirmation links. The confirmation email contains a signup_confirm URL with an identity verification key. The controller looks up that key, publishes the user resource, marks the account and identity as verified, emits #signup_confirm{id=UserId}, logs the user on, and redirects to #signup_confirm_redirect{} or the user's page.

Adding fields to the signup form

Extra person-resource fields can be added by combining template customization with the signup_form_fields fold notification.

The final email-signup form is rendered by _signup_with_email_step3.tpl. A site can override that template or one of its blocks to add inputs. For every input that should become a user resource property, add {Field, Validate} to the signup_form_fields fold result. Field can be an atom or binary. Validate decides whether the controller reads the field with z_context:get_q_validated/2 or with z_context:get_q/2. Values are trimmed, uploaded files are ignored, and values from the stored props payload take precedence over posted form values.

An observer can add fields like this:

observe_signup_form_fields(Fields, _Context) ->
    [
        {phone, false},
        {address_street_1, true}
        | Fields
    ].

For fields that are not plain user resource properties, observe #signup_check{} to inspect or rewrite Props and SignupProps before the user is created, or observe #signup_done{} to perform follow-up work after a successful signup.

Configuration

You can adjust this module’s behaviour with the following Module configuration:

KeyDefaultDescription
mod_signup.request_confirmtrueSend a signup confirmation e-mail to new users. If set to false, users are verified immediately.
mod_signup.username_equals_emailtrueIf true, the user’s e-mail address is also the username (users can log in with their e-mail). If false, users can choose a separate username.
mod_signup.email_uniquefalseIf true, a signup e-mail address may not already belong to another user account. It also may not match an e-mail identity on another resource where that identity has is_unique set. E-mail identities on non-account resources do not block signup when they are not marked unique. If false, multiple users can have the same verified e-mail address.
mod_signup.member_categorypersonName of the category that users created through sign up will be placed in.
mod_signup.content_groupempty stringName of the content group that users created through sign up will be placed in. The empty string means the default content group for the current ACL module.
mod_signup.depiction_as_mediumfalseIf set then any depiction URL is added as a medium record to the person who signed up. Normally the depiction is added as a separate depending image resource and connected from the person using a depiction predicate.

Config: Using the user’s e-mail address as username

By setting a configuration value, it is possible to use the entered email address as the username.

Set the configuration value mod_signup.username_equals_email to true.

This makes the username equal to the email address, so that the user can log in using his email address instead of a separate user name. Note that when you allow a user to change his email, take care to update the `{username_pw, {Username, Password}}` identity as well, otherwise the username remains equal to the old email address.

Notifications

signup_form_fields

Fold for determining which signup fields to validate. This is a list of {Fieldname, Validate} tuples, defaulting to:

[
    {name_first, true},
    {name_surname_prefix, false},
    {name_surname, true}
]

The email address is handled separately in the first signup step and is not part of the final form field fold.

Observers can add / remove fields using the accumulator value that is passed into the notification.

#identity_verification{ user_id = UserId, identity = Ident }

Send verification requests to unverified identities.

#signup_check{ props = UserProps, signup_props = SignupProps }

Fold for the signup preflight check. Allows to add extra user properties or abort the signup.

If no {ok, _Props1, SignupProps} is returned, but {error, Reason}, the signup is aborted.

#signup_done{ id = Id, is_verified = IsVerified, props = Props, signup_props = SignupProps }

Fired when a signup procedure is done and a user has been created.

#signup_confirm{ id = UserId }

Fired when a users have signed up and confirmed their identity (e.g. via e-mail).

#signup_confirm_redirect{ id = UserId }

Decide to which page a user gets redirected to after signup. User signup module handling registration, activation, and signup-related policies.

Accepted Events

This module handles the following notifier callbacks:

  • observe_identity_verification: Complete signup identity verification and continue the signup/logon flow when allowed.

  • observe_logon_ready_page: Return the url to redirect to when the user logged on, defaults to the user's personal page using z_auth:is_auth.

  • observe_signup: Add a new user or an existing person as user using z_ids:id.

  • observe_signup_url: Generate a link to the signup page, with additional signup properties stored as xs_props.

Edit on GitHub

Models

signup

Exported APIs:

Controllers

controller_signup

Controller which displays a form to sign up (rendered from signup.tpl ).

controller_signup_confirm

Controller which displays the confirmation page where the user can confirm his signup.

Dispatch rules

dispatch

Dispatch rules Name Path Resource Args signup [“signup”] controller_signup [] signup_confirm [“signup”,”confirm”]…

See also

Automatically add new users to a user group

Why When you create a person, you usually need to add it to a user group as well. You may want to automate this, in…

Referred by

Customizing the sign up and sign in form

You want to change parts of the form, or change its appearance.

All dispatch rules

All the dispatch rules from all modules. For a background on dispatch rules, see The URL dispatch system.

Notifications

At different moments in the lifecycle of the web request, Zotonic sends notifications. By observing these notifications…