controller_signup
Controller which displays a form to sign up (rendered from signup.tpl).
It also implements the necessary postbacks to perform the signup and log a user in.
Data flow
The signup page can be reached directly through the signup dispatch rule, or by
asking the notification system for a #signup_url{}. The mod_signup
observe_signup_url/2 observer stores the caller supplied arguments in
mod_server_storage:
#signup_url{
props = Props,
signup_props = SignupProps
}
Props are resource properties for the person that will be created or updated,
for example a prefilled email, name_first, or depiction_url. SignupProps
are signup control values and identities, for example {user_id, Id},
{ready_page, Url}, or {identity, {Type, Key, IsUnique, IsVerified}}.
The observer generates a random check id, stores
{CheckId, Props, SignupProps}, and returns the signup URL with xs=CheckId.
When this controller renders the page it reads the xs query argument, performs
m_server_storage:secure_lookup/2, and only accepts the stored payload when the
returned check id matches the query value. Accepted values are exposed to
signup.tpl as:
removed so the email step can still ask for an address.props: a map with prefilled resource properties. Empty email values aresignup_props: the stored signup properties as a proplist.email: the prefilled email fromprops, when present.
Without a valid xs, the controller renders with empty signup properties and
default props. The xs value itself is not posted back. Instead, the stored
payload is carried forward as template variables in each wire postback
(props=props signup_props=signup_props). This keeps the browser-visible form
state limited to the values the template already needs to render, while the
original xs token is only used to bootstrap the first page render.
The controller accepts these postbacks:
is new and local signup is possible, a short one-time code is mailed usingsignup_email_step1: validates and prechecks the email address. If the addressemail_signup_code.tpl. If the address is already known, or an external provider handles the domain, the second step shows a logon link and/or external provider buttons instead.
deleted and the account details form is rendered.signup_email_step2: checks the mailed one-time code. On success, the code is
checkbox, merges posted form properties with any prefilledsignup_email_step3: verifies the email did not change, checks the termsprops, combines identities fromsignup_propswith the verified email identity, creates or updates the user throughmod_signup:signup_existing/5, logs the user on, and sends a one-time authentication token to the client auth model for redirect.signup_go_step1: returns the browser UI to the first email step.
and sends a newsignup_resend_code: replaces the stored one-time code for the email addressemail_signup_code.tplmessage.
Template structure
The public signup page is signup.tpl. It extends base.tpl, adds the logon
CSS in html_head_extra, and fills content_area by including
_signup_box.tpl. Other pages can include _signup_box.tpl directly when they
need the signup UI without the surrounding page inheritance. The signup box
handles already logged-on users and otherwise includes:
_signup_with_email.tplfor the three-step email signup flow.all
SSO signup options._logon_extra.tpltemplates supplied by active authentication modules for
_signup_with_email.tpl includes _signup_with_email_step1.tpl for the first
email form and renders empty containers for steps two and three. The controller
fills those containers with _signup_with_email_step2.tpl and
_signup_with_email_step3.tpl after the corresponding postbacks.
_signup_with_email_step1.tpl renders the email address form and posts
signup_email_step1. If an email address was supplied through props, it shows
that address with a Change link. The Change postback re-renders
_signup_with_email_step1.tpl without the prefilled email so the visitor can
enter another address.
_signup_with_email_step2.tpl shows the selected email address, the mailed code
form, send status, resend action, existing-account logon link, external-provider
options, and error states.
_signup_with_email_step3.tpl renders the final signup form. It defines blocks
around the form, field set, individual field groups, and error area so sites can
override the shape of the final step. It uses the configuration exposed through
m.signup.config.username_equals_email to decide whether the username is hidden
and equal to the email address, or entered separately by the user.
Email address confirmation
There are two email checks in the complete signup lifecycle.
The first check happens before account creation. signup_email_step1 sends the
short code rendered by email_signup_code.tpl. Codes are stored in the
mod_signup gen_server under the tag {signup, EmailNorm}. They are replaced on
resend, expire by generational garbage collection, are rate-limit checked through
#auth_precheck{}, and are deleted after a successful signup_email_step2.
This confirms that the visitor can read the mailbox before the account is
created. The verified email is then added to the signup identities as
{identity, {email, Email, false, true}} unless an email identity was already
supplied in signup_props.
The second check is the account identity confirmation handled by mod_signup
and controller_signup_confirm. If signup is requested with confirmation
enabled and no non-password identity is already verified, mod_signup creates
the user unpublished and unverified, inserts unverified identities, and sends
email_verify.tpl through the #identity_verification{} observer. The email
contains a signup_confirm URL with the identity verification key.
controller_signup_confirm renders signup_confirm.tpl. That template extends
base.tpl and immediately posts the key back to the confirmation controller.
The confirmation controller looks up the identity by verification key, publishes
the user resource, marks the account and identity as verified, emits
#signup_confirm{id=UserId}, logs the user on, and redirects to the first
#signup_confirm_redirect{} result or to the user's page.