UseCase.rst 9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
.. ==================================================
.. ==================================================
.. ==================================================
.. Header hierarchy
.. ==
..  --
..   ^^
..    ""
..     ;;
..      ,,
..
.. --------------------------------------------used to the update the records specified ------
.. Best Practice T3 reST: https://docs.typo3.org/m/typo3/docs-how-to-document/master/en-us/WritingReST/CheatSheet.html
..             Reference: https://docs.typo3.org/m/typo3/docs-how-to-document/master/en-us/WritingReST/Index.html
.. Italic *italic*
.. Bold **bold**
.. Code ``text``
.. External Links: `Bootstrap <http://getbootstrap.com/>`_
.. Internal Link: :ref:downloadButton (default url text) or :ref:`download Button<downloadButton>` (explicit url text)
.. Add Images:    .. image:: ../Images/a4.jpg
..
..
.. Admonitions
..           .. note::   .. important::     .. tip::     .. warning::
.. Color:   (blue)       (orange)           (green)      (red)
..
.. Definition:
.. some text becomes strong (only one line)
..      description has to indented

.. -*- coding: utf-8 -*- with BOM.

.. include:: Includes.txt

.. _`use-case`:

Use Case
========

 * Create the request pages and tt-content records.
 * Copy the JSON form code to a new form (open Form in JSON mode).


.. _`self-registration`:

Self Registration
-----------------

Concept:

* Form 'Request password reset link'

  * Input: email address.
  * Send a mail with a URL (incl. a token) which is time limited.

    * Only send mail if the mail address is known.
    * If email is not found, the user should not be noticed.
    * Create a new Person.auth token.
    * Set Person.authExpired = NOW + ? days.

* Under the URL a form 'Set password' opens.

  * The user types in his new password.
  * On Save:

    * If the FE account does not exist, it will be created.
    * Set the FE user password.
    * Clear Person.authExpired

Request password reset link
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Table: Person
"""""""""""""

CREATE TABLE `Person` (
  `id` int(11) UNSIGNED NOT NULL,
  `lastName` varchar(64) NOT NULL DEFAULT '',
  `firstName` varchar(64) NOT NULL DEFAULT '',
  `email` varchar(128) NOT NULL,
  `account` varchar(128) NOT NULL,
  `auth`  varchar(32) NOT NULL,
  `authExpire` datetime NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8 PACK_KEYS=1;

Page: reset
"""""""""""

Page Alias: reset

QFQ content record::

    #
    # {{action:SE}}: passwordReset
    #
    # Empty: {{action:SE}}='' > shows the form angezeigt 'passwordReset'.
    # Given: {{action:SE}}='confirmation' > show confirmation.
    #
    form={{SELECT IF('{{action:SE}}' = '','passwordReset','') }}
    r=1

    10 {
      sql = SELECT '' FROM (SELECT '') AS fake WHERE '{{action:SE}}'='confirmation'
      head = <div class="alert alert-success">
               <p>Thank you.</p>
               <p>If the email address is known in our database, we sent a password reset link to it.</p>
               <p>The mail should be received during the next minutes. If not, please check you junk folder.</p>
               <p>To set a new password, please click on the link provided in the email.</p>
             </div>
    }

Form: passwordReset
"""""""""""""""""""

* Take care that there is one dummy person record with person.id=1

Form 'passwordReset'::

    {
        "title": "Password reset",
        "tableName": "Person",
        "permitNew": "never",
        "permitEdit": "always",
        "escapeTypeDefault": "c",
        "render": "bootstrap",
        "dirtyMode": "exclusive",
        "showButton": "save",
        "multiMode": "none",
        "forwardMode": "url-sip-skip-history",
        "forwardPage": "?id={{pageAlias:T}}&action=confirmation",
        "labelAlign": "default",
        "parameter": "submitButtonText = Send passwort reset email",
        "deleted": "no",
        "FormElement_ff": [
            {
                "enabled": "yes",
                "name": "email",
                "label": "Email",
                "mode": "show",
                "class": "native",
                "type": "text",
                "encode": "specialchar",
                "checkType": "email",
                "ord": 10,
            },
            {
                "enabled": "yes",
                "label": "Check for *example.com email",
                "mode": "show",
                "class": "action",
                "type": "beforeSave",
                "ord": 20,
                "parameter": "sqlValidate={{!SELECT 'fake' FROM (SELECT '')  AS fake WHERE '{{email:F:alnumx}}' LIKE '%example.com'  }}\r\n expectRecords=0\r\nmessageFail=Sorry, Password reset is not possible for *example.com.",
            },
            {
                "enabled": "yes",
                "label": "a) set auth, expire, b) send email",
                "mode": "show",
                "class": "action",
                "type": "sendMail",
                "encode": "specialchar",
                "checkType": "auto",
                "ord": 50,
                "value": "{{body:V::-}}",
                "parameter": "fillStoreVar={{!SELECT CONCAT(p.firstName , ' ', p.lastName) AS name, p.id AS _pId, @expire:=DATE_ADD(NOW(), INTERVAL 4 DAY) AS expireTs, QDATE_FORMAT(@expire) AS expire, p.email, '{{random:V}}' AS auth FROM Person AS p WHERE p.email='{{email:F:alnumx}}' AND p.email!='' LIMIT 1}}\r\n\r\nsendMailTo={{email:VE}}\r\nsendMailSubject=Password Reset\r\nsendMailFrom=webmaster@example.com\r\nsendMailGrId=123\r\nsendMailXId=456\r\nsendMailMode = html\r\n\r\n# Set token & expiration\r\nsqlAfter = {{UPDATE Person SET auth='{{auth:V}}', authExpire='{{expireTs:V}}' WHERE email='{{email:F:alnumx}}' AND email!='' LIMIT 1}}",
            }
        ]
    }

Set new password
^^^^^^^^^^^^^^^^

Page: set
"""""""""

Page Alias: set

QFQ content record::

#
# {{auth:CE}} - empty >> Form 'setPassword'
# {{auth:CE}} - unknown | expired >> Error message
# {{auth:SE}} - valid >> Set Password
#
# {{action:CE}} - 'thanks'

form={{SELECT IF( ISNULL(p.id), '', 'passwordSet' )
          FROM (SELECT '') AS fake
          LEFT JOIN Person AS p
            ON p.auth='{{auth:C:alnumx}}'
              AND p.auth!=''
              AND NOW()<p.authExpire }}

r={{SELECT IFNULL(p.id, 0) FROM (SELECT '') AS fake LEFT JOIN Person AS p ON p.auth='{{auth:C:alnumx}}' AND p.auth!='' AND NOW()<p.authExpire}}


10 {
  sql = SELECT IF( ISNULL(p.id)
                   , 'Token invalid'
                   , IF( NOW()<p.authExpire
                        ,''
                        , IF( p.authExpire=0, 'Password already set', 'Token expired') )
                 )
          FROM (SELECT '') AS fake
          LEFT JOIN Person AS p
            ON p.auth='{{auth:C:alnumx}}'
              AND p.auth!=''
          WHERE '{{action:SE}}'=''
              AND (ISNULL(p.id) OR NOW()>=p.authExpire)
  head = <div class="alert alert-warning" role="alert">
  tail = </div>
}

20.sql = SELECT 'Thanks for setting the password. Please <a href="?id=login">log in</a> now.'
           FROM (SELECT '') AS fake
           WHERE '{{action:SE}}'='thanks'

Form: passwordSet
"""""""""""""""""

Form 'passwordSet'::

    {
        "title": "Set password",
        "tableName": "Person",
        "permitNew": "never",
        "permitEdit": "always",
        "escapeTypeDefault": "c",
        "render": "bootstrap",
        "dirtyMode": "exclusive",
        "showButton": "save",
        "multiMode": "none",
        "forwardMode": "url-sip-skip-history",
        "forwardPage": "?{{pageAlias:T}}&action=thanks",
        "parameter": "submitButtonText='Set password'",
        "FormElement_ff": [
            {
                "enabled": "yes",
                "name": "myValue",
                "label": "Password",
                "mode": "show",
                "class": "native",
                "type": "password",
                "checkType": "pattern",
                "checkPattern": "[a-zA-Z0-9-_+ *\\\/.,:;]{10,}",
                "ord": 10,
                "parameter": "retype\r\nretypeLabel=Retype password\r\ndata-pattern-error=At least 10 characters are required. Valid characters: a-z A-Z 0-9 -_+*\/.,:;\r\nextraButtonPassword",
            },
            {
                "enabled": "yes",
                "label": "Update fe_user.password",
                "mode": "show",
                "class": "action",
                "type": "afterSave",
                "encode": "specialchar",
                "ord": 20,
                "parameter": "slaveId={{SELECT fe.uid FROM {{dbNameT3:Y}}.fe_users AS fe WHERE fe.username='{{email:RE}}' AND fe.username!='' AND fe.deleted=0 LIMIT 1}}\r\n\r\n# Create FE User. Please update values of `pid`, `usergroup` to your setup.\r\nsqlInsert = {{INSERT INTO {{dbNameT3:Y}}.fe_users ( `pid`, `usergroup`, `username`, `email`, `name`, `password`,`crdate`) VALUES ( 5 , 1 , '{{email:RE}}', '{{email:RE}}', '{{lastName:RE}}, {{firstName:RE}}', '{{myValue:FE:all:p}}',  UNIX_TIMESTAMP() ) }}\r\n\r\nsqlUpdate = {{UPDATE {{dbNameT3:Y}}.fe_users SET password='{{myValue:FE:all:p}}' WHERE uid={{slaveId:V0}}  }}\r\n\r\nsqlAfter={{UPDATE Person SET authExpire=0 WHERE id={{id:R}} }}",
            }
        ]
    }