3 [ -n "$include_users" ] && return 0
6 . "${_EXEC}/cgilite/session.sh"
7 . "${_EXEC}/cgilite/storage.sh"
9 USER_REGISTRATION="${USER_REGISTRATION:-true}"
10 USER_REQUIREEMAIL="${USER_REQUIREEMAIL:-true}"
12 HTTP_HOST="$(HEADER Host)"
13 MAILFROM="${MAILDOMAIN:-noreply@${HTTP_HOST%:*}}"
15 user_db="${_DATA}/users.db"
16 unset USER_ID USER_NAME USER_EMAIL
19 # UID UNAME STATUS (pending|active|deleted) EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
22 local user_id="$(SESSION_VAR user_id)"
23 local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
25 && read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE <<-EOF
26 $(grep "^${user_id} " "$user_db")
28 if [ "$STATUS" = active -a "$EXPIRE" -gt "$_DATE" ]; then
30 USER_NAME="$(UNSTRING "$UNAME")"
31 USER_EMAIL="$(UNSTRING "$EMAIL")"
36 { [ $# -gt 0 ] && printf %s "$*" || cat } \
42 /^[a-zA-Z][a-zA-Z0-9 -~]{2,127}$/!d;
48 { [ $# -gt 0 ] && printf %s "$*" || cat } \
50 # W3C recommended email regex
51 # https://html.spec.whatwg.org/multipage/input.html#email-state-(type=email)
52 /^[a-zA-Z0-9.!#$%&'\''*+\/=?^_`{|}~-]+@[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/p;
57 local uname="$(STRING "$1")"
58 local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
59 while read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE; do
60 [ "$EXPIRE" -gt "$_DATE" -a "$UNAME" = "$uname" ] && return 0
66 local email="$(STRING "$1")"
67 local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
68 while read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE; do
69 [ "$EXPIRE" -gt "$_DATE" -a "$EMAIL" = "$email" ] && return 0
75 local salt="$1" secret="$2" hash
76 hash="$(printf '%s\n%s\n' "$secret" "$salt" |sha256sum)"
77 printf '%s\n' "${hash% *}"
81 # reserve account, send registration mail
82 # preliminary uid, expiration, signature
84 local uname="$(POST uname |user_checkname)"
85 local email="$(POST email |user_checkemail)"
86 local pwsalt="$(randomid)"
87 local pw="$(POST pw |grep -m1 -xE '.{6,}' )" pwconfirm="$(POST pwconfirm)"
89 if [ "$USER_REGISTRATION" != true ]; then
90 REDIRECT "${_BASE}${PATH_INFO}#ERROR_REGISTRATION_DISABLED"
93 if [ "$USER_REQUIREEMAIL" = true ]; then
94 if [ ! "email" ]; then
95 REDIRECT "${_BASE}${PATH_INFO}#ERROR_EMAIL_INVALID"
96 elif user_emailexist "$email"; then
97 REDIRECT "${_BASE}${PATH_INFO}#ERROR_EMAIL_EXISTS"
98 elif LOCK "$user_db"; then
99 printf '%s \\ pending %s \\ \\ %i \\ \\\n' \
100 "$uid" "$(STRING "$email")" "$(( $_DATE + 86400 ))" \
103 sendmail -t -f "$MAILFROM" <<-EOF
106 Subject: Your account registration at ${HTTP_HOST%:*}
108 Someone tried to sign up for a user account using this email address.
110 You can activate your account using this link:
112 https://${HTTP_HOST%:*}/${_BASE}/?user_confirm=${uid}+$(session_mac "$uid")
114 This registration link will expire after 24 hours.
116 If you did not request an account at ${HTTP_HOST%:*}, then someone else
117 probably entered your email address by accident. In this case you shoud
118 simply ignore this message and we will remove your email address from
119 our database within the next day.
121 This is an automatic email. Any direct reply will not be received.
122 Your Account Registration Robot.
124 REDIRECT "${_BASE}${PATH_INFO}#USER_REGISTER_CONFIRM"
126 REDIRECT "${_BASE}${PATH_INFO}#ERROR_USER_NOLOCK"
129 elif [ "$USER_REQUIREEMAIL" != true ] then
130 if [ ! "$uname" ]; then
131 REDIRECT "${_BASE}${PATH_INFO}#ERROR_UNAME_INVALID"
132 elif user_nameexist "$uname"; then
133 REDIRECT "${_BASE}${PATH_INFO}#ERROR_UNAME_EXISTS"
134 elif [ ! "$pw" ]; then
135 REDIRECT "${_BASE}${PATH_INFO}#ERROR_PW_EMPTYTOOSHORT"
136 elif [ "$pw" != "$pwconfirm" ]; then
137 REDIRECT "${_BASE}${PATH_INFO}#ERROR_PW_MISMATCH"
138 elif LOCK "$user_db"; then
139 printf '%s %s active %s %s %s %i \\ \\\n' \
140 "$uid" "$(STRING "$uname")" "$(STRING "$email")" \
141 "$pwsalt" "$(user_pwhash "$pwsalt" "$pw")" \
142 "$(( $_DATE + 86400 * 730 ))" \
147 SESSION_BIND user_id "$uid"
149 REDIRECT "${_BASE}${PATH_INFO}#USER_REGISTER_CONFIRM"
151 REDIRECT "${_BASE}${PATH_INFO}#ERROR_USER_NOLOCK"
158 local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
159 local uid="$(POST uid |checkid)"
160 local signature="$(POST signature)"
161 local uname="$(POST uname |user_checkname)"
162 local pwsalt="$(randomid)"
163 local pw="$(POST pw |grep -m1 -xE '.{6,}' )" pwconfirm="$(POST pwconfirm)"
165 if [ "$signature" != "$(session_mac "$uid")" ]; then
166 REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_LINK_INVALID"
167 elif [ ! "$uname" ]; then
168 REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_UNAME_INVALID"
169 elif user_nameexist "$uname"; then
170 REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_UNAME_EXISTS"
171 elif [ ! "$pw" ]; then
172 REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_PW_EMPTYTOOSHORT"
173 elif [ "$pw" != "$pwconfirm" ]; then
174 REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_PW_MISMATCH"
175 elif LOCK "$user_db"; then
176 read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE <<-EOF
177 $(grep "^${uid} " "$user_db")
180 if [ "$STATUS" != pending -o "$EXPIRE" -le "$_DATE" ]; then
182 REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_LINK_INVALID"
184 printf '%s %s active %s %s %s %i %s %s\n' \
185 "$UID" "$(STRING "$uname")" "$EMAIL" \
186 "$pwsalt" "$(user_pwhash "$pwsalt" "$pw")" \
187 "$(( $_DATE + 86400 * 730 ))" "$DEVICES" "$FUTUREUSE" \
189 grep -v "^${uid} " "$user_db" >>"${user_db}.$$"
190 mv "${user_db}.$$" "${user_db}"
194 SESSION_BIND user_id "$UID"
195 REDIRECT "${_BASE}${PATH_INFO}#USER_REGISTER_CONFIRM"
198 REDIRECT "${_BASE}${PATH_INFO}#ERROR_USER_NOLOCK"
204 # keep logged in - device cookie?
205 # initialize new session!
206 local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
207 local uname="$(POST uname |STRING)" pw="$(POST pw)"
209 while read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE; do
210 if [ "$UNAME" = "$uname" -o "$EMAIL" = "$uname" ]; then
211 if [ "$STATUS" = active -a "$EXPIRE" -gt "$_DATE" -a "$PWHASH" = "$(user_pwhash "$PWSALT" "$pw")" ]; then
213 SESSION_BIND user_id "$UID"
214 REDIRECT "${_BASE}${PATH_INFO}#USER_LOGGED_IN"
218 REDIRECT "${_BASE}${PATH_INFO}#ERROR_INVALID_LOGIN"
222 # destroy cookie, destroy session
225 SET_COOKIE 0 session=""
226 SET_COOKIE 0 user_id=""
227 REDIRECT "${_BASE}${PATH_INFO}#USER_LOGGED_OUT"
241 [ "$REQUEST_METHOD" = POST ] && case "$(POST action)" in
242 user_register) user_register ;;
243 user_confirm) user_confirm ;;
244 user_login) user_login ;;
245 user_logout) user_logout ;;
255 if [ "$USER_REGISTRATION" != true ]; then
257 [div #user_register .disabled
258 User Registration is disabled.
261 elif [ "$USER_REQUIREEMAIL" = true ]; then
263 [form #user_register .registeremail method=POST
264 [p We will send an activation mail to your email address.
265 You can continue the signup process when you click on the
266 activation link in this email.]
267 [input type=email name=email placeholder="Email"]
268 [submit "action" "user_register" Sign Up]
271 elif [ "$USER_REQUIREEMAIL" != true ]; then
273 [form #user_register .registername method=POST
274 [input name=uname placeholder="Choose Username" tooltip="Your username may contain any character but the @ sign. It must be at least 3 characters long, and it must start with a letter." pattern="^\[a-zA-Z\]\[a-zA-Z0-9 -~\]{2,127}$" autocomplete=off]
275 [input type=pw placeholder="Choose Passphrase" pattern=".{4,}"]
276 [input type=pwconfirm placeholder="Confirm Passphrase" pattern=".{4,}"]
277 [submit "action" "user_register" Sign Up]
284 local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
285 local user_confirm="$(GET user_confirm)"
286 local uid="${user_confirm% *}" signature="${user_confirm#* }"
288 if [ "$signature" = "$(session_mac "$uid")" ]; then
289 read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE <<-EOF
290 $(grep "^${uid} " "$user_db")
292 if [ "$STATUS" = pending -a "$EXPIRE" -gt "$_DATE" ]; then
294 [form #user_confirm method=POST
295 [input type=hidden name=uid value="${uid}"]
296 [input type=hidden name=signature value="${signature}"]
297 [input disabled=disabled value="$(HTML "$EMAIL")"]
298 [input name=uname placeholder="Choose Username" tooltip="Your username may contain any character but the @ sign. It must be at least 3 characters long, and it must start with a letter." pattern="^\[a-zA-Z\]\[a-zA-Z0-9 -~\]{2,127}$" autocomplete=off]
299 [input type=pw placeholder="Choose Passphrase" pattern=".{4,}"]
300 [input type=pwconfirm placeholder="Confirm Passphrase" pattern=".{4,}"]
301 [submit "action" "user_confirm" Finish Registration]
306 [div #user_confirm .expired
307 [p This activation link is not valid anymore.]
313 [div #user_confirm .invalid
314 [p This activation link is invalid. Make sure you copied the whole activation link from your email and be careful not to include any line breaks.]
321 if [ ! "$USER_ID" ]; then
323 [form #user_login .login method=POST
324 [input name=uname placeholder="Username or Email" autocomplete=off]
325 [input type=password name=pw placeholder="Passphrase"]
326 [submit "action" "user_login" Login]
329 elif [ "$USER_ID" ]; then
331 [form #user_login .logout method=POST
332 [p You are currently logged in as "${USER_NAME}"]
333 [submit "action" "user_logout" Logout]